Show 'app is expired' screen instead of 'welcome' screen

This commit is contained in:
Scott Nonnenberg
2018-11-15 16:15:25 -08:00
parent af6f32ee05
commit 0378cdff82
7 changed files with 784 additions and 866 deletions

View File

@@ -1,4 +1,7 @@
{
"preLinkExpiredHeader": {
"message": "Time to upgrade"
},
"uninstallHeader": {
"message": "How to uninstall"
},

View File

@@ -741,88 +741,16 @@ sudo apt update && sudo apt install signal-desktop
<div id='step1' class='step'>
<div class='inner'>
<div class='step-body'>
<img id='signal-icon' src='/images/icon_250.png'/>
<h1>{{ installWelcome }}</h1>
<p>{{ installTagline }}</p>
</div>
<div class='nav'>
<div> <a class='button step2'>{{ installGetStartedButton }}</a> </div>
<span class='dot step1 selected'></span>
<span class='dot step2'></span>
<span class='dot step3'></span>
</div>
</div>
</div>
<div id='step2' class='step'>
<div class='inner'>
<div class='step-body'>
<img id='signal-phone' src='/images/signal-phone.png'>
<p>{{{ installSignalLink }}}</p>
</div>
<div class='nav'>
<div> <a class='button step3'>{{ installIHaveSignalButton }}</a> </div>
<span class='dot step1'></span>
<span class='dot step2 selected'></span>
<span class='dot step3'></span>
</div>
</div>
</div>
<div id='step3' class='step'>
<div class='inner'>
<div class='step-body'>
<div id="qr"></div>
<p>{{ installAndroidInstructions }}</p>
</div>
<div class='nav'>
<span class='dot step1'></span>
<span class='dot step2'></span>
<span class='dot step3 selected'></span>
</div>
</div>
</div>
<form id='step4' class='step'>
<div class='inner'>
<div class='step-body'>
<p>{{ installLinkingWithNumber }}</p>
<h2 class='number'></h2>
<img id='signal-computer' src='/images/signal-laptop.png'>
<p>{{ installComputerName }}</p>
<div>
<input type='text' id='device-name' spellcheck='false' maxlength='50' />
</div>
<img class='banner-image' src='/images/icon_128.png'>
<div class='header'>{{ preLinkExpiredHeader }}</div>
<div class='body-text-wide'>{{ startExportIntroParagraph1 }}</div>
</div>
<div class='nav'>
<div>
<input type='submit' class='button' id='sync' value='{{ installFinalButton }}' />
<a class='button get-new-version' target='_blank' href='https://signal.org/download'>{{ getNewVersion }}</a>
</div>
</div>
</div>
</form>
<div id='step5' class='step'>
<div class='inner'>
<div class='step-body'>
<img id='signal-icon' src='/images/icon_250.png'/>
<div class='progress-dialog'>
<p class='status'></p>
<div class='bar-container'><div class='bar progress-bar'></div></div>
</div>
</div>
<div class='nav'>
</div>
</div>
</div>
<div id='stepTooManyDevices' class='step'>
<div class='inner error-dialog clearfix'>
<div class='panel step-body'>{{ installTooManyDevices }}</div>
<div class='nav'>
<button class='ok step3'>{{ ok }}</button>
</div>
</div>
</div>
</script>

View File

@@ -172,9 +172,12 @@
extension.windows.open({
id: id,
url: url,
bounds: { width: 800, height: 666, },
minWidth: 800,
minHeight: 666
bounds: {
width: 580,
height: 440,
},
minWidth: 600,
minHeight: 360
});
}
};

View File

@@ -7,138 +7,20 @@
Whisper.InstallView = Whisper.View.extend({
templateName: 'install_flow_template',
id: 'install',
className: 'main',
render_attributes: function() {
var playStoreHref = 'https://play.google.com/store/apps/details?id=org.thoughtcrime.securesms';
var appStoreHref = 'https://itunes.apple.com/us/app/signal-private-messenger/id874139669';
var twitterHref = 'https://twitter.com/whispersystems';
return {
installWelcome: i18n('installWelcome'),
installTagline: i18n('installTagline'),
installGetStartedButton: i18n('installGetStartedButton'),
installSignalLink: this.i18n_with_links('installSignalLinks', playStoreHref, appStoreHref),
installIHaveSignalButton: i18n('installGotIt'),
installFollowUs: this.i18n_with_links('installFollowUs', twitterHref),
installAndroidInstructions: i18n('installAndroidInstructions'),
installLinkingWithNumber: i18n('installLinkingWithNumber'),
installComputerName: i18n('installComputerName'),
installFinalButton: i18n('installFinalButton'),
installTooManyDevices: i18n('installTooManyDevices'),
ok: i18n('ok'),
preLinkExpiredHeader: i18n('preLinkExpiredHeader'),
startExportIntroParagraph1: i18n('startExportIntroParagraph1'),
getNewVersion: i18n('getNewVersion'),
};
},
initialize: function(options) {
this.counter = 0;
console.log('initialize!', this);
this.render();
var deviceName = textsecure.storage.user.getDeviceName();
if (!deviceName) {
deviceName = 'Chrome';
if (navigator.userAgent.match('Mac OS')) {
deviceName += ' on Mac';
} else if (navigator.userAgent.match('Linux')) {
deviceName += ' on Linux';
} else if (navigator.userAgent.match('Windows')) {
deviceName += ' on Windows';
}
}
this.$('#device-name').val(deviceName);
this.$('#step1').show();
this.connect();
this.on('disconnected', this.reconnect);
},
connect: function() {
this.clearQR();
var accountManager = getAccountManager();
accountManager.registerSecondDevice(
this.setProvisioningUrl.bind(this),
this.confirmNumber.bind(this),
this.incrementCounter.bind(this)
).catch(this.handleDisconnect.bind(this));
},
handleDisconnect: function(e) {
if (e.message === 'websocket closed') {
this.showConnectionError();
this.trigger('disconnected');
} else if (e.name === 'HTTPError' && e.code == 411) {
this.showTooManyDevices();
} else {
throw e;
}
},
reconnect: function() {
setTimeout(this.connect.bind(this), 10000);
},
close: function() {
this.remove();
},
events: function() {
return {
'click .error-dialog .ok': 'connect',
'click .step1': this.selectStep.bind(this, 1),
'click .step2': this.selectStep.bind(this, 2),
'click .step3': this.selectStep.bind(this, 3)
};
},
clearQR: function() {
this.$('#qr').text(i18n("installConnecting"));
},
setProvisioningUrl: function(url) {
this.$('#qr').html('');
new QRCode(this.$('#qr')[0]).makeCode(url);
},
confirmNumber: function(number) {
var parsed = libphonenumber.parse(number);
if (!libphonenumber.isValidNumber(parsed)) {
throw new Error('Invalid number ' + number);
}
this.$('#step4 .number').text(libphonenumber.format(
parsed,
libphonenumber.PhoneNumberFormat.INTERNATIONAL
));
this.selectStep(4);
this.$('#device-name').focus();
return new Promise(function(resolve, reject) {
this.$('#step4 .cancel').click(function(e) {
reject();
});
this.$('#step4').submit(function(e) {
e.stopPropagation();
e.preventDefault();
var name = this.$('#device-name').val();
name = name.replace(/\0/g,''); // strip unicode null
if (name.trim().length === 0) {
this.$('#device-name').focus();
return;
}
this.$('.progress-dialog .status').text(i18n('installGeneratingKeys'));
this.selectStep(5);
resolve(name);
}.bind(this));
}.bind(this));
},
incrementCounter: function() {
this.$('.progress-dialog .bar').css('width', (++this.counter * 100 / 100) + '%');
},
selectStep: function(step) {
this.$('.step').hide();
this.$('#step' + step).show();
},
showSync: function() {
this.$('.progress-dialog .status').text(i18n('installSyncingGroupsAndContacts'));
this.$('.progress-dialog .bar').addClass('progress-bar-striped active');
},
showTooManyDevices: function() {
this.selectStep('TooManyDevices');
},
showConnectionError: function() {
this.$('#qr').text(i18n("installConnectionFailed"));
},
hideDots: function() {
this.$('#step3 .nav .dot').hide();
}
});
})();

View File

@@ -7,7 +7,7 @@
<link href='/images/icon_128.png' rel='shortcut icon'>
</head>
<body>
<div id='install' class='main'>
<div id='install' class='migration-flow'>
</div>
<script type="text/javascript" src="js/components.js"></script>

File diff suppressed because it is too large Load Diff

View File

@@ -1,366 +1,7 @@
@import 'variables';
@import 'mixins';
@import 'global';
@import 'intlTelInput';
@import 'progress';
.iti-flag {
// override intlTelInput's flags image location
background: url("/images/flags.png");
}
* {
box-sizing: border-box;
}
html,body {
height: 100%;
}
body {
margin: 0;
font-family: $roboto;
position: relative;
background: #2090ea;
color: white;
text-align: center;
font-size: 16px;
overflow: auto;
}
.clearfix:before,
.clearfix:after {
display: table;
content: " ";
}
.clearfix:after {
clear: both;
}
input, button, select, textarea {
font-family: inherit;
font-size: inherit;
line-height: inherit;
}
#install {
display: none;
height: 100%;
// 666px is the minimum window height in chromium.js
@media screen and (max-height: 665px) {
height: 666px;
}
}
.main {
padding: 70px 0 50px;
}
.step {
display: none;
height: 100%;
}
.inner {
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
height: 100%;
.step-body {
margin-top: auto;
width: 100%;
max-width: 600px;
}
}
#signal-computer,
#signal-phone {
max-width: 50%;
max-height: 250px;
}
p {
max-width: 35em;
margin: 1em auto;
line-height: 1.5em;
font-size: 1.2em;
font-weight: bold;
}
a {
cursor: pointer;
&, &:visited, &:hover {
text-decoration: none;
}
}
.button {
display: inline-block;
text-transform: uppercase;
border: none;
font-weight: bold;
min-width: 300px;
padding: 0.5em;
margin: 0.5em 0;
background: white;
color: $blue;
}
.nav {
width: 100%;
bottom: 50px;
margin-top: auto;
padding: 0 20px;
.button {
margin-bottom: 3em;
}
.dot {
display: inline-block;
cursor: pointer;
margin: 10px;
width: 20px;
height: 20px;
border-radius: 10px;
background: white;
border: solid 5px $blue;
&.selected {
background: $blue_l;
}
}
}
.link {
&:hover, &:focus {
background: rgba(255,255,255,0.3);
outline: none;
}
&, &:visited, &:hover {
padding: 0 3px;
color: white;
font-weight: bold;
border-bottom: dashed 2px white;
text-decoration: none;
}
}
.container {
min-width: 650px;
}
h1 {
font-size: 30pt;
font-weight: normal;
padding-bottom: 10px;
}
h3.step {
margin-top: 0;
font-weight: bold;
}
.help {
border-top: 2px solid $grey_l;
padding: 1.5em 0.1em;
}
.install {
display: inline-block;
margin-top: 90px;
}
#qr {
display: inline-block;
min-height: 266px;
img {
border: 5px solid white;
}
canvas {
display: none;
}
}
#device-name {
border: none;
border-bottom: 1px solid white;
padding: 8px;
background: transparent;
color: white;
font-weight: bold;
text-align: center;
&::selection, a::selection {
color: $grey_d;
background: white;
}
&::-moz-selection, a::-moz-selection {
color: $grey_d;
background: white;
}
&:focus {
outline: none;
}
&:hover, &:focus {
background: rgba(255,255,255,0.1);
}
}
#verifyCode,
#code,
#number {
box-sizing: border-box;
width: 100%;
display: block;
margin-bottom: 0.5em;
text-align: center;
}
#request-voice,
#request-sms {
box-sizing: border-box;
}
#request-sms {
width: 57%;
float: right;
}
#request-voice {
width: 40%;
float: left;
}
.number-container {
position: relative;
margin-bottom: 0.5em;
}
.number-container .intl-tel-input,
.number-container .number {
width: 100%;
}
.number-container::after {
visibility: hidden;
content: ' ';
display: inline-block;
border-radius: 1.5em;
width: 1.5em;
height: 1.5em;
line-height: 1.5em;
color: #ffffff;
position: absolute;
top: 0;
left: 100%;
margin: 3px 8px;
text-align: center;
}
.number-container.valid::after {
visibility: visible;
content: '';
background-color: #0f9d58;
color: #ffffff;
}
.number-container.invalid::after {
visibility: visible;
content: '!';
background-color: #f44336;
color: #ffffff;
}
#error {
color: white;
font-weight: bold;
padding: 0.5em;
text-align: center;
}
#error { background-color: #f44336; }
#error:before {
content: '\26a0';
padding-right: 0.5em;
}
.narrow {
margin: auto;
box-sizing: border-box;
width: 275px;
max-width: 100%;
}
ul.country-list {
min-width: 197px !important;
}
.confirmation-dialog, .progress-dialog, .error-dialog {
padding: 1em;
text-align: left;
}
.number { text-align: center; }
.confirmation-dialog, .error-dialog {
button {
float: right;
margin-left: 10px;
}
}
.progress-dialog {
text-align: center;
padding: 1em;
width: 100%;
max-width: 600px;
margin: auto;
.status { padding: 1em; }
.bar-container {
height: 1em;
background-color: $grey_l;
border: solid 1px white;
}
.bar {
width: 0;
height: 100%;
background-color: $blue_l;
transition: width 0.25s;
&.active {
}
}
}
.error-dialog {
display: none;
}
.modal-container {
display: none;
position: absolute;
width: 100%;
height: 100%;
background: rgba(0,0,0,0.1);
top: 0;
padding-top: 10em;
text-align: center;
.modal-main {
display: inline-block;
width: 80%;
max-width: 500px;
border: solid 2px $blue;
background: white;
margin: 10% auto;
box-shadow: 0 0 5px 3px rgba(darken($blue, 30%), 0.2);
h4 {
background-color: $blue;
color: white;
padding: 1em;
margin: 0;
text-align: left;
}
}
}
.intl-tel-input .country-list {
text-align: left;
}
.intl-tel-input .country-list .country .country-name {
color: #000;
}