diff --git a/_locales/en/messages.json b/_locales/en/messages.json
index 95f077898..bd7e2f439 100644
--- a/_locales/en/messages.json
+++ b/_locales/en/messages.json
@@ -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",
diff --git a/preload.js b/preload.js
index eb964c2c3..340327a87 100644
--- a/preload.js
+++ b/preload.js
@@ -265,5 +265,3 @@ window.addEventListener('contextmenu', e => {
e.preventDefault();
}
});
-
-// Blocking
diff --git a/stylesheets/_modal.scss b/stylesheets/_modal.scss
index f7ab93a63..495cc97df 100644
--- a/stylesheets/_modal.scss
+++ b/stylesheets/_modal.scss
@@ -31,6 +31,10 @@
width: 100%;
min-width: 300px;
}
+
+ &__input-group {
+ min-width: 300px;
+ }
}
.create-group-dialog,
diff --git a/stylesheets/_session_password.scss b/stylesheets/_session_password.scss
index 99bd3d1de..8e4d14c30 100644
--- a/stylesheets/_session_password.scss
+++ b/stylesheets/_session_password.scss
@@ -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;
}
}
diff --git a/ts/components/SessionPasswordPrompt.tsx b/ts/components/SessionPasswordPrompt.tsx
index 521744b05..564e50e5e 100644
--- a/ts/components/SessionPasswordPrompt.tsx
+++ b/ts/components/SessionPasswordPrompt.tsx
@@ -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 ?? (
- ) : (
-
);
const errorSection = !this.state.clearDataView && (
@@ -183,7 +180,7 @@ class SessionPasswordPromptInner extends React.PureComponent<{}, State> {
>
)}
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}
/>
-
;
+ 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 (
-
+
{items.map(item => {
const itemIsActive = item.value === activeItem;
diff --git a/ts/components/conversation/message/message-content/MessageContentWithStatus.tsx b/ts/components/conversation/message/message-content/MessageContentWithStatus.tsx
index aaed10ead..4fb722004 100644
--- a/ts/components/conversation/message/message-content/MessageContentWithStatus.tsx
+++ b/ts/components/conversation/message/message-content/MessageContentWithStatus.tsx
@@ -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}
/>
-
+
diff --git a/ts/components/dialog/DeleteAccountModal.tsx b/ts/components/dialog/DeleteAccountModal.tsx
index 687d93701..4047d69d9 100644
--- a/ts/components/dialog/DeleteAccountModal.tsx
+++ b/ts/components/dialog/DeleteAccountModal.tsx
@@ -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 (
+ <>
+ {window.i18n('deleteAccountWarning')}
+
+ {window.i18n('dialogClearAllDataDeletionQuestion')}
+
+
+
+ {
+ 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 (
+
+ {props.deleteMode === 'device_and_network'
+ ? window.i18n('areYouSureDeleteEntireAccount')
+ : window.i18n('areYouSureDeleteDeviceOnly')}
+
+ );
+};
+
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(DEVICE_ONLY);
const dispatch = useDispatch();
@@ -175,84 +219,44 @@ export const DeleteAccountModal = () => {
onClose={onClickCancelHandler}
showExitIcon={true}
>
-
-
-
-
-
+ ) : (
+
-
+ )}
+
{
- 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}
/>
{
- setDeleteDeviceOnly(true);
+ dispatch(updateDeleteAccountModal(null));
}}
- disabled={deleteEverythingWithNetwork || deleteDeviceOnly}
+ disabled={isLoading}
/>
- {deleteEverythingWithNetwork && (
-
- )}
-
- {deleteDeviceOnly && (
-
- )}
-
-
- {(deleteDeviceOnly || deleteEverythingWithNetwork) && (
-
- {
- if (deleteDeviceOnly) {
- void onDeleteEverythingLocallyOnly();
- } else if (deleteEverythingWithNetwork) {
- void onDeleteEverythingAndNetworkData();
- }
- }}
- disabled={isLoading}
- />
-
- {
- dispatch(updateDeleteAccountModal(null));
- }}
- disabled={isLoading}
- />
-
- )}
-
diff --git a/ts/components/dialog/SessionPasswordDialog.tsx b/ts/components/dialog/SessionPasswordDialog.tsx
index 394fc5b47..870211b96 100644
--- a/ts/components/dialog/SessionPasswordDialog.tsx
+++ b/ts/components/dialog/SessionPasswordDialog.tsx
@@ -55,15 +55,15 @@ export class SessionPasswordDialog extends React.Component
{
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 {
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 {
ToastUtils.pushToastSuccess(
'setPasswordSuccessToast',
window.i18n('changePasswordTitle'),
- window.i18n('changePasswordToastDescription'),
- 'lock'
+ window.i18n('changePasswordToastDescription')
);
this.props.onOk();
diff --git a/ts/components/icon/Icons.tsx b/ts/components/icon/Icons.tsx
index b55bc9970..55771ab5f 100644
--- a/ts/components/icon/Icons.tsx
+++ b/ts/components/icon/Icons.tsx
@@ -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',
diff --git a/ts/components/settings/section/CategoryPermissions.tsx b/ts/components/settings/section/CategoryPermissions.tsx
index 788be2f97..41deb614f 100644
--- a/ts/components/settings/section/CategoryPermissions.tsx
+++ b/ts/components/settings/section/CategoryPermissions.tsx
@@ -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 () => {
diff --git a/ts/types/LocalizerKeys.ts b/ts/types/LocalizerKeys.ts
index 90c94c0b7..8394717c3 100644
--- a/ts/types/LocalizerKeys.ts
+++ b/ts/types/LocalizerKeys.ts
@@ -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'