Update device naming flow during link and sync

This commit is contained in:
trevor-signal 2024-11-06 15:00:55 -05:00 committed by GitHub
parent 1653a2b546
commit d4b871af43
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 130 additions and 37 deletions

View file

@ -4747,6 +4747,10 @@
"messageformat": "Cancel transfer", "messageformat": "Cancel transfer",
"description": "Text of the cancel button at the bottom of backup import screen" "description": "Text of the cancel button at the bottom of backup import screen"
}, },
"icu:BackupImportScreen__security-description": {
"messageformat": "Messages and chat info are protected by end-to-end encryption, including the sync process. <learnMoreLink>Learn more</learnMoreLink>",
"description": "Text shown while importing messages & chats from the user's primary device."
},
"icu:BackupImportScreen__cancel-confirmation__title": { "icu:BackupImportScreen__cancel-confirmation__title": {
"messageformat": "Cancel transfer?", "messageformat": "Cancel transfer?",
"description": "Title of the cancel confirmation modal in the backup import screen" "description": "Title of the cancel confirmation modal in the backup import screen"

View file

@ -8,12 +8,17 @@
width: 100vw; width: 100vw;
height: 100vh; height: 100vh;
justify-content: center; flex-direction: column;
align-items: center; align-items: center;
} }
.InstallScreenBackupImportStep__content { .InstallScreenBackupImportStep__content {
display: flex;
flex-direction: column;
justify-content: center;
text-align: center; text-align: center;
margin-top: 64px;
flex: 1;
} }
.InstallScreenBackupImportStep__title { .InstallScreenBackupImportStep__title {
@ -55,9 +60,6 @@
@include button-focus-outline; @include button-focus-outline;
@include font-body-1-bold; @include font-body-1-bold;
position: absolute;
bottom: 48px;
@include light-theme() { @include light-theme() {
color: $color-ultramarine; color: $color-ultramarine;
} }
@ -66,3 +68,56 @@
color: $color-ultramarine-light; color: $color-ultramarine-light;
} }
} }
.InstallScreenBackupImportStep__footer {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
margin-bottom: 36px;
min-height: 94px;
gap: 26px;
}
.InstallScreenBackupImportStep__security {
display: flex;
flex-direction: column;
align-items: center;
max-width: 336px;
&--icon::after {
@include light-theme {
@include color-svg(
'../images/icons/v3/lock/lock.svg',
rgba($color-gray-60, 0.8)
);
}
@include dark-theme {
@include color-svg('../images/icons/v3/lock/lock.svg', $color-gray-25);
}
content: '';
display: block;
height: 16px;
width: 16px;
margin-bottom: 4px;
}
&--description {
@include font-caption;
text-align: center;
@include light-theme {
color: rgba($color-gray-60, 0.8);
}
@include dark-theme {
color: $color-gray-25;
}
a {
text-decoration: none;
}
}
}

View file

@ -12,6 +12,8 @@ import { ConfirmationDialog } from '../ConfirmationDialog';
import { InstallScreenSignalLogo } from './InstallScreenSignalLogo'; import { InstallScreenSignalLogo } from './InstallScreenSignalLogo';
import { roundFractionForProgressBar } from '../../util/numbers'; import { roundFractionForProgressBar } from '../../util/numbers';
import { missingCaseError } from '../../util/missingCaseError'; import { missingCaseError } from '../../util/missingCaseError';
import { SYNCING_MESSAGES_SECURITY_URL } from '../../types/support';
import { I18n } from '../I18n';
// We can't always use destructuring assignment because of the complexity of this props // We can't always use destructuring assignment because of the complexity of this props
// type. // type.
@ -115,12 +117,17 @@ export function InstallScreenBackupImportStep({
); );
} }
const learnMoreLink = (parts: Array<string | JSX.Element>) => (
<a href={SYNCING_MESSAGES_SECURITY_URL} rel="noreferrer" target="_blank">
{parts}
</a>
);
return ( return (
<div className="InstallScreenBackupImportStep"> <div className="InstallScreenBackupImportStep">
<TitlebarDragArea /> <TitlebarDragArea />
<InstallScreenSignalLogo /> <InstallScreenSignalLogo />
<div className="InstallScreenBackupImportStep__content"> <div className="InstallScreenBackupImportStep__content">
<h3 className="InstallScreenBackupImportStep__title"> <h3 className="InstallScreenBackupImportStep__title">
{i18n('icu:BackupImportScreen__title')} {i18n('icu:BackupImportScreen__title')}
@ -130,16 +137,28 @@ export function InstallScreenBackupImportStep({
{i18n('icu:BackupImportScreen__description')} {i18n('icu:BackupImportScreen__description')}
</div> </div>
</div> </div>
<div className="InstallScreenBackupImportStep__footer">
<div className="InstallScreenBackupImportStep__security">
<div className="InstallScreenBackupImportStep__security--icon" />
<div className="InstallScreenBackupImportStep__security--description">
<I18n
i18n={i18n}
id="icu:BackupImportScreen__security-description"
components={{ learnMoreLink }}
/>
</div>
</div>
{backupStep === InstallScreenBackupStep.Download && ( {backupStep === InstallScreenBackupStep.Download && (
<button <button
className="InstallScreenBackupImportStep__cancel" className="InstallScreenBackupImportStep__cancel"
type="button" type="button"
onClick={confirmCancel} onClick={confirmCancel}
> >
{i18n('icu:BackupImportScreen__cancel')} {i18n('icu:BackupImportScreen__cancel')}
</button> </button>
)} )}
</div>
{isConfirmingCancel && ( {isConfirmingCancel && (
<ConfirmationDialog <ConfirmationDialog

View file

@ -28,6 +28,7 @@ import type { BoundActionCreatorsMapObject } from '../../hooks/useBoundActions';
import { useBoundActions } from '../../hooks/useBoundActions'; import { useBoundActions } from '../../hooks/useBoundActions';
import * as log from '../../logging/log'; import * as log from '../../logging/log';
import { backupsService } from '../../services/backups'; import { backupsService } from '../../services/backups';
import OS from '../../util/os/osMain';
const SLEEP_ERROR = new TimeoutError(); const SLEEP_ERROR = new TimeoutError();
@ -318,26 +319,30 @@ function startInstaller(): ThunkAction<
} }
provisionerByBaton.set(baton, provisioner); provisionerByBaton.set(baton, provisioner);
// Switch to next UI phase if (provisioner.isLinkAndSync()) {
dispatch({ dispatch(finishInstall({ deviceName: OS.getName() || 'Signal Desktop' }));
type: QR_CODE_SCANNED, } else {
payload: { // Show screen to choose device name
deviceName: dispatch({
window.textsecure.storage.user.getDeviceName() || type: QR_CODE_SCANNED,
window.getHostName() || payload: {
'', deviceName:
baton, window.textsecure.storage.user.getDeviceName() ||
}, window.getHostName() ||
}); '',
baton,
},
});
// And feed it the CI data if present // And feed it the CI data if present
const { SignalCI } = window; const { SignalCI } = window;
if (SignalCI != null) { if (SignalCI != null) {
dispatch( dispatch(
finishInstall({ finishInstall({
deviceName: SignalCI.deviceName, deviceName: SignalCI.deviceName,
}) })
); );
}
} }
}; };
} }
@ -356,8 +361,9 @@ function finishInstall(
return async (dispatch, getState) => { return async (dispatch, getState) => {
const state = getState(); const state = getState();
strictAssert( strictAssert(
state.installer.step === InstallScreenStep.ChoosingDeviceName, state.installer.step === InstallScreenStep.ChoosingDeviceName ||
'Not choosing device name' state.installer.step === InstallScreenStep.QrCodeNotScanned,
'Wrong step'
); );
const { baton } = state.installer; const { baton } = state.installer;
@ -367,6 +373,13 @@ function finishInstall(
'Provisioner is not waiting for device info' 'Provisioner is not waiting for device info'
); );
if (state.installer.step === InstallScreenStep.QrCodeNotScanned) {
strictAssert(
provisioner.isLinkAndSync(),
'Can only skip device naming if link & sync'
);
}
// Cleanup // Cleanup
controllerByBaton.delete(baton); controllerByBaton.delete(baton);
provisionerByBaton.delete(baton); provisionerByBaton.delete(baton);
@ -563,8 +576,8 @@ export function reducer(
if (action.type === SHOW_BACKUP_IMPORT) { if (action.type === SHOW_BACKUP_IMPORT) {
if ( if (
// Downloading backup after linking // Downloading backup after linking
state.step !== InstallScreenStep.ChoosingDeviceName && state.step !== InstallScreenStep.QrCodeNotScanned &&
// Restarting backup download on startup // Restarting backup download on startup
state.step !== InstallScreenStep.NotStarted state.step !== InstallScreenStep.NotStarted
) { ) {

View file

@ -9,3 +9,5 @@ export const LINK_SIGNAL_DESKTOP =
'https://support.signal.org/hc/articles/360007320451#desktop_multiple_device'; 'https://support.signal.org/hc/articles/360007320451#desktop_multiple_device';
export const SAFETY_NUMBER_URL = export const SAFETY_NUMBER_URL =
'https://support.signal.org/hc/articles/360007060632'; 'https://support.signal.org/hc/articles/360007060632';
export const SYNCING_MESSAGES_SECURITY_URL =
'https://support.signal.org/hc/articles/360007320391';