fix: update copy and clear account modal

pull/2515/head
Audric Ackermann 2 years ago
parent dcf2f96c9f
commit d944379dd7

@ -63,7 +63,7 @@
"offline": "Offline",
"debugLog": "Debug Log",
"showDebugLog": "Export Logs",
"shareBugDetails": "Share some details to help us resolve your issue. Export your logs, then upload the file though Session's Help Desk.",
"shareBugDetails": "Export your logs, then upload the file though Session's Help Desk.",
"goToReleaseNotes": "Go to Release Notes",
"goToSupportPage": "Go to Support Page",
"about": "About",
@ -113,7 +113,7 @@
"deleteConversationConfirmation": "Permanently delete the messages in this conversation?",
"clear": "Clear",
"clearAllData": "Clear All Data",
"deleteAccountWarning": "This will permanently delete your messages, and contacts.",
"deleteAccountWarning": "This will permanently delete your messages and contacts.",
"deleteContactConfirmation": "Are you sure you want to delete this conversation?",
"quoteThumbnailAlt": "Thumbnail of image from quoted message",
"imageAttachmentAlt": "Image attached to message",
@ -136,7 +136,7 @@
"spellCheckTitle": "Spell Check",
"spellCheckDescription": "Enable spell check when typing messages.",
"spellCheckDirty": "You must restart Session to apply your new settings",
"readReceiptSettingDescription": "See and share typing indicators in one-to-one chats.",
"readReceiptSettingDescription": "Send read receipts in one-to-one chats.",
"readReceiptSettingTitle": "Read Receipts",
"typingIndicatorsSettingDescription": "See and share typing indicators in one-to-one chats.",
"typingIndicatorsSettingTitle": "Typing Indicators",
@ -280,14 +280,14 @@
"recoveryPhraseSavePromptMain": "Your recovery phrase is the master key to your Session ID — you can use it to restore your Session ID if you lose access to your device. Store your recovery phrase in a safe place, and don't give it to anyone.",
"invalidOpenGroupUrl": "Invalid URL",
"copiedToClipboard": "Copied to clipboard",
"passwordViewTitle": "Type In Your Password",
"unlock": "Unlock",
"passwordViewTitle": "Enter Password",
"password": "Password",
"setPassword": "Set Password",
"changePassword": "Change Password",
"createPassword": "Create your password",
"removePassword": "Remove Password",
"maxPasswordAttempts": "Invalid Password. Would you like to reset the database?",
"typeInOldPassword": "Please type in your old password",
"typeInOldPassword": "Please enter your current password",
"invalidOldPassword": "Old password is invalid",
"invalidPassword": "Invalid password",
"noGivenPassword": "Please enter your password",
@ -413,11 +413,11 @@
"dialogClearAllDataDeletionFailedDesc": "Data not deleted with an unknown error. Do you want to delete data from just this device?",
"dialogClearAllDataDeletionFailedTitleQuestion": "Do you want to delete data from just this device?",
"dialogClearAllDataDeletionFailedMultiple": "Data not deleted by those Service Nodes: $snodes$",
"dialogClearAllDataDeletionQuestion": "Would you like to clear only this device, or delete your entire account?",
"deviceOnly": "Device Only",
"entireAccount": "Entire Account",
"dialogClearAllDataDeletionQuestion": "Would you like to clear this device only, or delete your data from the network as well?",
"deviceOnly": "Clear Device Only",
"entireAccount": "Clear Device and Network",
"areYouSureDeleteDeviceOnly": "Are you sure you want to delete your device data only?",
"areYouSureDeleteEntireAccount": "Are you sure you want to delete your entire account, including the network data?",
"areYouSureDeleteEntireAccount": "Are you sure you want to delete your data from the network? If you continue, you will not be able to restore your messages or contacts.",
"iAmSure": "I am sure",
"recoveryPhraseSecureTitle": "You're almost finished!",
"recoveryPhraseRevealMessage": "Secure your account by saving your recovery phrase. Reveal your recovery phrase then store it safely to secure it.",
@ -453,7 +453,8 @@
"callMissedCausePermission": "Call missed from '$name$' because you need to enable the 'Voice and video calls' permission in the Privacy Settings.",
"callMissedNotApproved": "Call missed from '$name$' as you haven't approved this conversation yet. Send a message to them first.",
"callMediaPermissionsDescription": "Enables voice and video calls to and from other users.",
"callMediaPermissionsDialogContent": "The current implementation of voice/video calls will expose your IP address to the Oxen Foundation servers and the calling/called user.",
"callMediaPermissionsDialogContent": "Your IP is visible to your call partner and an Oxen Foundation server while using beta calls. Are you sure you want to enable Voice and Video Calls?",
"callMediaPermissionsDialogTitle": "Voice and Video Calls (Beta)",
"startedACall": "You called $name$",
"answeredACall": "Call with $name$",
"trimDatabase": "Trim Database",

@ -265,5 +265,3 @@ window.addEventListener('contextmenu', e => {
e.preventDefault();
}
});
// Blocking

@ -31,6 +31,10 @@
width: 100%;
min-width: 300px;
}
&__input-group {
min-width: 300px;
}
}
.create-group-dialog,

@ -84,7 +84,7 @@
}
#password-prompt-input {
width: 100%;
width: 65%;
color: #fff;
background-color: #2e2e2e;
margin-top: 2 * $session-margin-lg;
@ -93,8 +93,7 @@
border: none;
border-radius: 2px;
text-align: center;
font-size: 24px;
letter-spacing: 5px;
font-size: 18px;
font-family: $session-font-default;
}
}

@ -5,7 +5,6 @@ import { SessionIcon } from './icon';
import { withTheme } from 'styled-components';
import autoBind from 'auto-bind';
import { SessionButton, SessionButtonColor, SessionButtonType } from './basic/SessionButton';
import { Constants } from '../session';
import { SessionSpinner } from './basic/SessionSpinner';
interface State {
@ -70,17 +69,15 @@ class SessionPasswordPromptInner extends React.PureComponent<{}, State> {
id="password-prompt-input"
type="password"
defaultValue=""
placeholder={' '}
placeholder={window.i18n('enterPassword')}
onKeyUp={this.onKeyUp}
ref={input => {
this.inputRef = input;
}}
/>
);
const infoIcon = this.state.clearDataView ? (
const infoIcon = this.state.clearDataView ?? (
<SessionIcon iconType="warning" iconSize={35} iconColor="#ce0000" />
) : (
<SessionIcon iconType="lock" iconSize={35} iconColor={Constants.UI.COLORS.GREEN} />
);
const errorSection = !this.state.clearDataView && (
<div className="password-prompt-error-section">
@ -183,7 +180,7 @@ class SessionPasswordPromptInner extends React.PureComponent<{}, State> {
</>
)}
<SessionButton
text={window.i18n('unlock')}
text={window.i18n('done')}
buttonType={SessionButtonType.BrandOutline}
buttonColor={SessionButtonColor.Green}
onClick={this.initLogin}

@ -28,6 +28,7 @@ const StyledInput = styled.input<{
background: ${props => props.selectedColor};
}
`;
// tslint:disable: use-simple-attributes
const StyledLabel = styled.label<{
selectedColor: string;
@ -79,12 +80,11 @@ export const SessionRadio = (props: Props) => {
outlineOffset={outlineOffset}
selectedColor={selectedColor}
/>
<StyledLabel
role="button"
onClick={clickHandler}
selectedColor={selectedColor}
filledSize={filledSize}
filledSize={filledSize - 1}
outlineOffset={outlineOffset}
beforeMargins={beforeMargins}
aria-label={label}

@ -1,36 +1,43 @@
import React, { useEffect, useState } from 'react';
import styled from 'styled-components';
import styled, { CSSProperties } from 'styled-components';
import { SessionRadio } from './SessionRadio';
interface Props {
// tslint:disable: react-unused-props-and-state
initialItem: string;
items: Array<any>;
items: Array<{ value: string; label: string }>;
group: string;
onClick: (selectedValue: string) => any;
style?: CSSProperties;
}
const StyledFieldSet = styled.fieldset`
display: flex;
flex-direction: column;
gap: var(--margins-xs);
border: none;
margin-inline-start: var(--margins-sm);
margin-top: var(--margins-sm);
& > div {
padding-block: 7px;
}
& > div + div {
border-top: 1px solid var(--color-session-border);
}
`;
export const SessionRadioGroup = (props: Props) => {
const { items, group, initialItem, style } = props;
const [activeItem, setActiveItem] = useState('');
const { items, group, initialItem } = props;
useEffect(() => {
setActiveItem(initialItem);
}, []);
return (
<StyledFieldSet id={group}>
<StyledFieldSet id={group} style={style}>
{items.map(item => {
const itemIsActive = item.value === activeItem;

@ -44,8 +44,8 @@ const StyledMessageContentContainer = styled.div<{ direction: 'left' | 'right' }
}
`;
const StyledMessageWithAuthor = styled.div<{ isOutgoing: boolean }>`
max-width: ${props => (props.isOutgoing ? 'calc(100% - 17px)' : '100%')};
const StyledMessageWithAuthor = styled.div<{ isIncoming: boolean }>`
max-width: ${props => (props.isIncoming ? '100%' : 'calc(100% - 17px)')};
`;
export const MessageContentWithStatuses = (props: Props) => {
@ -126,7 +126,7 @@ export const MessageContentWithStatuses = (props: Props) => {
messageId={messageId}
isCorrectSide={isIncoming}
/>
<StyledMessageWithAuthor isOutgoing={!isIncoming}>
<StyledMessageWithAuthor isIncoming={isIncoming}>
<MessageAuthorText messageId={messageId} />
<MessageContent messageId={messageId} isDetailView={isDetailView} />

@ -6,12 +6,12 @@ import { forceSyncConfigurationNowIfNeeded } from '../../session/utils/syncUtils
import { updateConfirmModal, updateDeleteAccountModal } from '../../state/ducks/modalDialog';
import { SpacerLG } from '../basic/Text';
import { SessionButton, SessionButtonColor } from '../basic/SessionButton';
import { SessionHtmlRenderer } from '../basic/SessionHTMLRenderer';
import { SessionSpinner } from '../basic/SessionSpinner';
import { SessionWrapperModal } from '../SessionWrapperModal';
import { Data } from '../../data/data';
import { deleteAllLogs } from '../../node/logs';
import { SessionRadioGroup } from '../basic/SessionRadioGroup';
const deleteDbLocally = async () => {
window?.log?.info('last message sent successfully. Deleting everything');
@ -127,10 +127,54 @@ async function deleteEverythingAndNetworkData() {
}
}
const DEVICE_ONLY = 'device_only';
const DEVICE_AND_NETWORK = 'device_and_network';
type DeleteModes = typeof DEVICE_ONLY | typeof DEVICE_AND_NETWORK;
const DescriptionBeforeAskingConfirmation = (props: {
deleteMode: DeleteModes;
setDeleteMode: (deleteMode: DeleteModes) => void;
}) => {
const { deleteMode, setDeleteMode } = props;
return (
<>
<span className="session-confirm-main-message">{window.i18n('deleteAccountWarning')}</span>
<span className="session-confirm-main-message">
{window.i18n('dialogClearAllDataDeletionQuestion')}
</span>
<SpacerLG />
<SessionRadioGroup
group="delete_account"
initialItem={deleteMode}
onClick={value => {
if (value === DEVICE_ONLY || value === DEVICE_AND_NETWORK) {
setDeleteMode(value);
}
}}
items={[
{ label: window.i18n('deviceOnly'), value: DEVICE_ONLY },
{ label: window.i18n('entireAccount'), value: 'device_and_network' },
]}
/>
</>
);
};
const DescriptionWhenAskingConfirmation = (props: { deleteMode: DeleteModes }) => {
return (
<span className="session-confirm-main-message">
{props.deleteMode === 'device_and_network'
? window.i18n('areYouSureDeleteEntireAccount')
: window.i18n('areYouSureDeleteDeviceOnly')}
</span>
);
};
export const DeleteAccountModal = () => {
const [isLoading, setIsLoading] = useState(false);
const [deleteDeviceOnly, setDeleteDeviceOnly] = useState(false);
const [deleteEverythingWithNetwork, setDeleteEverythingWithNetwork] = useState(false);
const [askingConfirmation, setAskingConfirmation] = useState(false);
const [deleteMode, setDeleteMode] = useState<DeleteModes>(DEVICE_ONLY);
const dispatch = useDispatch();
@ -175,84 +219,44 @@ export const DeleteAccountModal = () => {
onClose={onClickCancelHandler}
showExitIcon={true}
>
<SpacerLG />
<div className="session-modal__centered">
<SessionHtmlRenderer
tag="span"
className="session-confirm-main-message"
html={window.i18n('deleteAccountWarning')}
/>
<SessionHtmlRenderer
tag="span"
className="session-confirm-main-message"
html={window.i18n('dialogClearAllDataDeletionQuestion')}
{askingConfirmation ? (
<DescriptionWhenAskingConfirmation deleteMode={deleteMode} />
) : (
<DescriptionBeforeAskingConfirmation
deleteMode={deleteMode}
setDeleteMode={setDeleteMode}
/>
<SpacerLG />
)}
<div className="session-modal__centered">
<div className="session-modal__button-group">
<SessionButton
text={window.i18n('entireAccount')}
text={window.i18n('clear')}
buttonColor={SessionButtonColor.Danger}
onClick={() => {
setDeleteEverythingWithNetwork(true);
if (!askingConfirmation) {
setAskingConfirmation(true);
return;
}
if (deleteMode === 'device_only') {
void onDeleteEverythingLocallyOnly();
} else if (deleteMode === 'device_and_network') {
void onDeleteEverythingAndNetworkData();
}
}}
disabled={deleteEverythingWithNetwork || deleteDeviceOnly}
disabled={isLoading}
/>
<SessionButton
text={window.i18n('deviceOnly')}
text={window.i18n('cancel')}
buttonColor={SessionButtonColor.Primary}
onClick={() => {
setDeleteDeviceOnly(true);
dispatch(updateDeleteAccountModal(null));
}}
disabled={deleteEverythingWithNetwork || deleteDeviceOnly}
disabled={isLoading}
/>
</div>
<SpacerLG />
{deleteEverythingWithNetwork && (
<SessionHtmlRenderer
tag="span"
className="session-confirm-main-message"
html={window.i18n('areYouSureDeleteEntireAccount')}
/>
)}
{deleteDeviceOnly && (
<SessionHtmlRenderer
tag="span"
className="session-confirm-main-message"
html={window.i18n('areYouSureDeleteDeviceOnly')}
/>
)}
<SpacerLG />
{(deleteDeviceOnly || deleteEverythingWithNetwork) && (
<div className="session-modal__button-group">
<SessionButton
text={window.i18n('iAmSure')}
buttonColor={SessionButtonColor.Danger}
onClick={() => {
if (deleteDeviceOnly) {
void onDeleteEverythingLocallyOnly();
} else if (deleteEverythingWithNetwork) {
void onDeleteEverythingAndNetworkData();
}
}}
disabled={isLoading}
/>
<SessionButton
text={window.i18n('cancel')}
buttonColor={SessionButtonColor.Primary}
onClick={() => {
dispatch(updateDeleteAccountModal(null));
}}
disabled={isLoading}
/>
</div>
)}
<SessionSpinner loading={isLoading} />
</div>
</SessionWrapperModal>

@ -55,15 +55,15 @@ export class SessionPasswordDialog extends React.Component<Props, State> {
case 'change':
placeholders = [
window.i18n('typeInOldPassword'),
window.i18n('enterPassword'),
window.i18n('confirmPassword'),
window.i18n('enterNewPassword'),
window.i18n('confirmNewPassword'),
];
break;
case 'remove':
placeholders = [window.i18n('enterPassword'), window.i18n('confirmPassword')];
placeholders = [window.i18n('enterPassword')];
break;
default:
placeholders = [window.i18n('enterNewPassword'), window.i18n('confirmNewPassword')];
placeholders = [window.i18n('createPassword'), window.i18n('confirmPassword')];
}
const confirmButtonColor =
@ -184,8 +184,7 @@ export class SessionPasswordDialog extends React.Component<Props, State> {
ToastUtils.pushToastSuccess(
'setPasswordSuccessToast',
window.i18n('setPasswordTitle'),
window.i18n('setPasswordToastDescription'),
'lock'
window.i18n('setPasswordToastDescription')
);
this.props.onOk();
@ -223,8 +222,7 @@ export class SessionPasswordDialog extends React.Component<Props, State> {
ToastUtils.pushToastSuccess(
'setPasswordSuccessToast',
window.i18n('changePasswordTitle'),
window.i18n('changePasswordToastDescription'),
'lock'
window.i18n('changePasswordToastDescription')
);
this.props.onOk();

@ -32,7 +32,6 @@ export type SessionIconType =
| 'hangup'
| 'info'
| 'link'
| 'lock'
| 'messageRequest'
| 'microphone'
| 'microphoneFull'
@ -279,12 +278,6 @@ export const icons = {
viewBox: '0 0 283.842 283.842',
ratio: 1,
},
lock: {
path:
'M417.684,188.632H94.316c-9.923,0-17.965,8.042-17.965,17.965v239.532c0,7.952,5.234,14.965,12.863,17.222l161.684,47.906 c1.665,0.497,3.383,0.743,5.102,0.743c1.719,0,3.437-0.246,5.108-0.743l161.684-47.906c7.623-2.258,12.857-9.27,12.857-17.222 V206.596C435.649,196.674,427.607,188.632,417.684,188.632z M399.719,432.715L256,475.298l-143.719-42.583V224.561h287.439 V432.715z M256,0c-69.345,0-125.754,56.949-125.754,126.952v76.052h35.93v-76.052c0-50.188,40.295-91.022,89.825-91.022 s89.825,40.834,89.825,91.022v76.65h35.93v-76.65C381.754,56.949,325.339,0,256,0z M256,308.398c-9.923,0-17.965,8.042-17.965,17.965v47.906c0,9.923,8.042,17.965,17.965,17.965 c9.923,0,17.965-8.042,17.965-17.965v-47.906C273.965,316.44,265.923,308.398,256,308.398z',
viewBox: '0 0 512 512',
ratio: 1,
},
messageRequest: {
path:
'M68.987 7.718H27.143c-2.73 0-5.25.473-7.508 1.417-2.257.945-4.357 2.363-6.248 4.253-1.89 1.89-3.308 3.99-4.253 6.248-.945 2.257-1.417 4.778-1.417 7.508V67.99c0 2.73.472 5.25 1.417 7.508.945 2.258 2.363 4.357 4.253 6.248 1.942 1.891 4.043 3.359 6.3 4.252 2.258.945 4.726 1.418 7.456 1.418h17.956c2.101 0 3.833 1.732 3.833 3.832 0 .473-.105.893-.21 1.313-.683 2.521-1.418 5.041-2.258 7.455-.893 2.574-1.837 4.988-2.888 7.352-.525 1.207-1.155 2.361-1.837 3.57 3.675-1.629 7.14-3.518 10.343-5.619 3.36-2.205 6.51-4.672 9.397-7.35 2.94-2.73 5.565-5.723 7.98-8.926.735-.996 1.89-1.521 3.045-1.521H87.94c2.73 0 5.198-.473 7.455-1.418 2.258-.945 4.358-2.363 6.301-4.252 1.89-1.891 3.308-3.99 4.253-6.248.944-2.258 1.417-4.779 1.417-7.508V27.249c0-2.73-.473-5.25-1.417-7.508-.945-2.258-2.363-4.357-4.253-6.248s-3.99-3.308-6.248-4.252c-2.258-.945-4.777-1.418-7.508-1.418H68.987v-.105zm-7.282 47.97h-9.976V54.61c0-1.833.188-3.327.574-4.471.386-1.155.958-2.193 1.721-3.143.762-.951 2.474-2.619 5.136-5.005 1.416-1.251 2.124-2.396 2.124-3.435 0-1.047-.287-1.852-.851-2.434-.574-.573-1.435-.864-2.59-.864-1.247 0-2.269.446-3.083 1.338-.816.883-1.335 2.444-1.561 4.657l-10.191-1.368c.349-4.054 1.711-7.314 4.078-9.787 2.376-2.473 6.015-3.706 10.917-3.706 3.818 0 6.893.863 9.24 2.58 3.184 2.338 4.778 5.441 4.778 9.321 0 1.61-.412 3.172-1.237 4.666-.815 1.493-2.501 3.327-5.037 5.48-1.766 1.523-2.887 2.735-3.353 3.657-.456.914-.689 2.116-.689 3.592zm-10.325 2.87h10.693v8.532H51.38v-8.532zM46.097.053H87.94c3.675 0 7.141.683 10.396 1.995 3.202 1.312 6.143 3.308 8.768 5.933 2.626 2.625 4.621 5.565 5.934 8.768 1.312 3.203 1.994 6.667 1.994 10.396V67.99c0 3.729-.683 7.193-1.994 10.396-1.313 3.201-3.308 6.141-5.934 8.768-2.625 2.625-5.565 4.566-8.768 5.932-3.202 1.313-6.668 1.996-10.396 1.996H74.395c-2.362 2.992-4.935 5.826-7.665 8.4-3.255 3.045-6.72 5.773-10.448 8.189-3.728 2.467-7.718 4.621-11.971 6.457-4.2 1.838-8.715 3.361-13.44 4.621-1.365.367-2.835-.053-3.833-1.156-1.417-1.574-1.26-3.988.315-5.406 2.205-1.943 4.095-3.938 5.618-5.934 1.47-1.941 2.678-3.938 3.57-5.984v-.053c.998-2.205 1.89-4.463 2.678-6.721.263-.787.525-1.627.788-2.467H27.091c-3.675 0-7.14-.684-10.396-1.996-3.203-1.313-6.143-3.307-8.768-5.932-2.625-2.625-4.62-5.566-5.933-8.768C.682 75.078 0 71.613 0 67.938V27.091c0-3.676.682-7.141 1.995-10.396 1.313-3.203 3.308-6.143 5.933-8.768 2.625-2.625 5.565-4.62 8.768-5.933S23.363 0 27.091 0h18.953l.053.053z',

@ -13,6 +13,7 @@ const toggleCallMediaPermissions = async (triggerUIUpdate: () => void) => {
if (!currentValue) {
window.inboxStore?.dispatch(
updateConfirmModal({
title: window.i18n('callMediaPermissionsDialogTitle'),
message: window.i18n('callMediaPermissionsDialogContent'),
okTheme: SessionButtonColor.Danger,
onClickOk: async () => {

@ -127,6 +127,7 @@ export type LocalizerKeys =
| 'mediaPermissionsTitle'
| 'replyingToMessage'
| 'welcomeToYourSession'
| 'createPassword'
| 'editMenuCopy'
| 'leftTheGroup'
| 'timerOption_30_minutes'
@ -146,6 +147,7 @@ export type LocalizerKeys =
| 'joinOpenGroupAfterInvitationConfirmationDesc'
| 'invalidNumberError'
| 'contextMenuNoSuggestions'
| 'callMediaPermissionsDialogTitle'
| 'recoveryPhraseRevealButtonText'
| 'banUser'
| 'primaryColorBlue'
@ -153,7 +155,6 @@ export type LocalizerKeys =
| 'recoveryPhraseRevealMessage'
| 'showRecoveryPhrase'
| 'autoUpdateSettingDescription'
| 'unlock'
| 'remove'
| 'restoreUsingRecoveryPhrase'
| 'cannotUpdateDetail'

Loading…
Cancel
Save