diff --git a/_locales/en/messages.json b/_locales/en/messages.json index 94a1fede4..7aa0796c7 100644 --- a/_locales/en/messages.json +++ b/_locales/en/messages.json @@ -1035,6 +1035,15 @@ "unpairDevice": { "message": "Unlink Device" }, + "unpairDeviceWarning": { + "message": "Are you sure you want to unlink this device?", + "description": "Warning for device unlinking in settings view" + }, + "unpairDeviceWarningSub": { + "message": + "Unlinking this device will delete all history, including all messages, sessions, and contacts from this device.", + "description": "Warning description for device unlinking in settings view" + }, "deviceUnpaired": { "message": "Device Unlinked" }, diff --git a/app/sql.js b/app/sql.js index 82b70e6cc..7b4be3393 100644 --- a/app/sql.js +++ b/app/sql.js @@ -2750,16 +2750,9 @@ async function removeAll() { db.serialize(() => { promise = Promise.all([ db.run('BEGIN TRANSACTION;'), + ...getRemoveConfigurationPromises(), db.run('DELETE FROM conversations;'), - db.run('DELETE FROM identityKeys;'), - db.run('DELETE FROM items;'), db.run('DELETE FROM messages;'), - db.run('DELETE FROM preKeys;'), - db.run('DELETE FROM sessions;'), - db.run('DELETE FROM signedPreKeys;'), - db.run('DELETE FROM unprocessed;'), - db.run('DELETE FROM contactPreKeys;'), - db.run('DELETE FROM contactSignedPreKeys;'), db.run('DELETE FROM attachment_downloads;'), db.run('DELETE FROM messages_fts;'), db.run('COMMIT TRANSACTION;'), @@ -2769,6 +2762,22 @@ async function removeAll() { await promise; } +function getRemoveConfigurationPromises() { + return [ + db.run('DELETE FROM identityKeys;'), + db.run('DELETE FROM items;'), + db.run('DELETE FROM preKeys;'), + db.run('DELETE FROM sessions;'), + db.run('DELETE FROM signedPreKeys;'), + db.run('DELETE FROM unprocessed;'), + db.run('DELETE FROM contactPreKeys;'), + db.run('DELETE FROM contactSignedPreKeys;'), + db.run('DELETE FROM servers;'), + db.run('DELETE FROM lastHashes;'), + db.run('DELETE FROM seenMessages;'), + ]; +} + // Anything that isn't user-visible data async function removeAllConfiguration() { let promise; @@ -2776,14 +2785,7 @@ async function removeAllConfiguration() { db.serialize(() => { promise = Promise.all([ db.run('BEGIN TRANSACTION;'), - db.run('DELETE FROM identityKeys;'), - db.run('DELETE FROM items;'), - db.run('DELETE FROM preKeys;'), - db.run('DELETE FROM sessions;'), - db.run('DELETE FROM signedPreKeys;'), - db.run('DELETE FROM unprocessed;'), - db.run('DELETE FROM contactPreKeys;'), - db.run('DELETE FROM contactSignedPreKeys;'), + ...getRemoveConfigurationPromises(), db.run('COMMIT TRANSACTION;'), ]); }); diff --git a/libtextsecure/outgoing_message.js b/libtextsecure/outgoing_message.js index eb2e5bf8f..540d8e0a6 100644 --- a/libtextsecure/outgoing_message.js +++ b/libtextsecure/outgoing_message.js @@ -302,7 +302,8 @@ OutgoingMessage.prototype = { let thisDeviceMessageType = this.messageType; if ( thisDeviceMessageType !== 'pairing-request' && - thisDeviceMessageType !== 'friend-request' + thisDeviceMessageType !== 'friend-request' && + thisDeviceMessageType !== 'onlineBroadcast' ) { try { const conversation = ConversationController.get(devicePubKey); diff --git a/stylesheets/_session.scss b/stylesheets/_session.scss index ac39ea49c..03168a8c5 100644 --- a/stylesheets/_session.scss +++ b/stylesheets/_session.scss @@ -295,19 +295,21 @@ textarea { display: flex; align-items: center; justify-content: center; - font-family: $session-font-accent; + font-family: $session-font-default; border-radius: 50%; font-weight: 700; background: $session-color-danger; color: $session-color-white; text-align: center; - span { + div { position: relative; sup { - font-size: 130%; position: absolute; + font-size: 1.3em; + top: -0.5em; + margin-left: -0.125em; } } @@ -693,7 +695,8 @@ label { font-size: $session-font-md; } &-sub-message { - margin-top: 5px; + text-align: center; + margin-top: 20px; } } @@ -1385,10 +1388,6 @@ input { opacity: 0.8; margin-bottom: $session-margin-xs; } - - .session-confirm-sub-message { - text-align: center; - } } } diff --git a/ts/components/LeftPane.tsx b/ts/components/LeftPane.tsx index babd60a8e..6d677da68 100644 --- a/ts/components/LeftPane.tsx +++ b/ts/components/LeftPane.tsx @@ -172,7 +172,9 @@ export class LeftPane extends React.Component { } private renderSettingSection() { - return ; + const { isSecondaryDevice } = this.props; + + return ; } private renderChannelSection() { diff --git a/ts/components/session/LeftPaneSettingSection.tsx b/ts/components/session/LeftPaneSettingSection.tsx index b540e9afd..eec1bae01 100644 --- a/ts/components/session/LeftPaneSettingSection.tsx +++ b/ts/components/session/LeftPaneSettingSection.tsx @@ -15,12 +15,16 @@ import { SessionIcon, SessionIconSize, SessionIconType } from './icon'; import { SessionSearchInput } from './SessionSearchInput'; import { SessionSettingCategory } from './settings/SessionSettings'; +interface Props { + isSecondaryDevice: boolean; +} + export interface State { settingCategory: SessionSettingCategory; searchQuery: string; } -export class LeftPaneSettingSection extends React.Component { +export class LeftPaneSettingSection extends React.Component { public constructor(props: any) { super(props); @@ -30,6 +34,7 @@ export class LeftPaneSettingSection extends React.Component { }; this.setCategory = this.setCategory.bind(this); + this.onDeleteAccount = this.onDeleteAccount.bind(this); } public componentDidMount() { @@ -140,41 +145,61 @@ export class LeftPaneSettingSection extends React.Component { ); } - public renderBottomButtons(): JSX.Element { - const deleteAccount = window.i18n('deleteAccount'); + public renderBottomButtons(): JSX.Element | undefined { + const { isSecondaryDevice } = this.props; + + const dangerButtonText = isSecondaryDevice + ? window.i18n('unpairDevice') + : window.i18n('deleteAccount'); const showSeed = window.i18n('showSeed'); return (
- + {!isSecondaryDevice && ( + + )}
); } public onDeleteAccount() { - const params = { - title: window.i18n('deleteAccount'), - message: window.i18n('deleteAccountWarning'), - messageSub: window.i18n('deleteAccountWarningSub'), + const { isSecondaryDevice } = this.props; + + const title = window.i18n( + isSecondaryDevice ? 'unpairDevice' : 'deleteAccount' + ); + + const message = window.i18n( + isSecondaryDevice ? 'unpairDeviceWarning' : 'deleteAccountWarning' + ); + + const messageSub = window.i18n( + isSecondaryDevice ? 'unpairDeviceWarningSub' : 'deleteAccountWarningSub' + ); + + window.confirmationDialog({ + title, + message, + messageSub, resolve: window.deleteAccount, okTheme: 'danger', - }; - - window.confirmationDialog(params); + }); } public getCategories() { + const { isSecondaryDevice } = this.props; + return [ { id: SessionSettingCategory.Appearance, @@ -199,6 +224,7 @@ export class LeftPaneSettingSection extends React.Component { { id: SessionSettingCategory.Devices, title: window.i18n('devicesSettingsTitle'), + hidden: isSecondaryDevice, }, ]; } diff --git a/ts/components/session/RegistrationTabs.tsx b/ts/components/session/RegistrationTabs.tsx index e80b95420..fdc4d655c 100644 --- a/ts/components/session/RegistrationTabs.tsx +++ b/ts/components/session/RegistrationTabs.tsx @@ -713,13 +713,8 @@ export class RegistrationTabs extends React.Component<{}, State> { } private async resetRegistration() { - await window.Signal.Data.removeAllIdentityKeys(); - await window.Signal.Data.removeAllPrivateConversations(); - window.Whisper.Registration.remove(); - // Do not remove all items since they are only set - // at startup. - window.textsecure.storage.remove('identityKey'); - window.textsecure.storage.remove('secondaryDeviceStatus'); + await window.Signal.Data.removeAll(); + await window.storage.fetch(); window.ConversationController.reset(); await window.ConversationController.load(); window.Whisper.RotateSignedPreKeyListener.stop(window.Whisper.events); diff --git a/ts/components/session/SessionNotificationCount.tsx b/ts/components/session/SessionNotificationCount.tsx index 97f565189..957e3180a 100644 --- a/ts/components/session/SessionNotificationCount.tsx +++ b/ts/components/session/SessionNotificationCount.tsx @@ -30,28 +30,24 @@ export class SessionNotificationCount extends React.Component { const MAX_SINGLE_DIGIT = 9; const overflow = typeof count === 'number' && count > MAX_SINGLE_DIGIT; - const fontSizeVal = overflow ? size / 2 : size / 2 + 2; - const fontSize = `${fontSizeVal}px`; - const bubbleStyle = { width: `${size}px`, height: `${size}px`, + fontSize: `${size}px`, }; + const fontSize = overflow ? '0.5em' : '0.6em'; + const countStyle = { fontSize, - marginTop: overflow ? `${size / 8}px` : '0px', - marginLeft: overflow ? `-${size / 4}px` : '0px', - }; - - const supStyle = { - top: `-${size * (3 / 8)}px`, + marginTop: overflow ? '0.35em' : '0em', + marginLeft: overflow ? '-0.45em' : '0em', }; const countElement: JSX.Element = overflow ? ( <> {MAX_SINGLE_DIGIT} - + + + ) : ( <>{count} @@ -68,7 +64,7 @@ export class SessionNotificationCount extends React.Component { style={bubbleStyle} role="button" > - {countElement} +
{countElement}
)}