signal-desktop/js/views/migration_view.js
2017-08-28 14:01:51 -07:00

181 lines
5.5 KiB
JavaScript

;(function () {
'use strict';
window.Whisper = window.Whisper || {};
var State = {
DISCONNECTING: 1,
EXPORTING: 2,
COMPLETE: 3
};
Whisper.Migration = {
isComplete: function() {
return storage.get('migrationState') === State.COMPLETE;
},
inProgress: function() {
return storage.get('migrationState') > 0 || this.everComplete();
},
markComplete: function(target) {
storage.put('migrationState', State.COMPLETE);
storage.put('migrationEverCompleted', true);
if (target) {
storage.put('migrationStorageLocation', target);
}
},
cancel: function() {
storage.remove('migrationState');
},
beginExport: function() {
storage.put('migrationState', State.EXPORTING);
return Whisper.Backup.backupToDirectory();
},
init: function() {
storage.put('migrationState', State.DISCONNECTING);
Whisper.events.trigger('start-shutdown');
},
everComplete: function() {
return Boolean(storage.get('migrationEverCompleted'));
},
getExportLocation: function() {
return storage.get('migrationStorageLocation');
}
};
Whisper.MigrationView = Whisper.View.extend({
templateName: 'app-migration-screen',
className: 'app-loading-screen',
events: {
'click .export': 'onClickExport',
'click .debug-log': 'onClickDebugLog'
},
initialize: function() {
if (!Whisper.Migration.inProgress()) {
return;
}
// We could be wedged in an 'in progress' state, the migration was started then the
// app restarted in the middle.
if (Whisper.Migration.everComplete()) {
// If the user has ever successfully exported before, we'll show the 'finished'
// screen with the 'Export again' button.
Whisper.Migration.markComplete();
} else if (!Whisper.Migration.isComplete()) {
// This takes the user back to the very beginning of the process.
Whisper.Migration.cancel();
}
},
render_attributes: function() {
var message;
var exportButton;
var hideProgress = Whisper.Migration.isComplete();
var debugLogButton = i18n('submitDebugLog');
if (this.error) {
return {
message: i18n('exportError'),
hideProgress: true,
exportButton: i18n('exportAgain'),
debugLogButton: i18n('submitDebugLog'),
};
}
switch (storage.get('migrationState')) {
case State.COMPLETE:
var location = Whisper.Migration.getExportLocation() || i18n('selectedLocation');
message = i18n('exportComplete', location);
exportButton = i18n('exportAgain');
debugLogButton = null;
break;
case State.EXPORTING:
message = i18n('exporting');
break;
case State.DISCONNECTING:
message = i18n('migrationDisconnecting');
break;
default:
hideProgress = true;
message = i18n('exportInstructions');
exportButton = i18n('export');
debugLogButton = null;
}
return {
hideProgress: hideProgress,
message: message,
exportButton: exportButton,
debugLogButton: debugLogButton,
};
},
onClickDebugLog: function() {
this.openDebugLog();
},
openDebugLog: function() {
this.closeDebugLog();
this.debugLogView = new Whisper.DebugLogView();
this.debugLogView.$el.appendTo(this.el);
},
closeDebugLog: function() {
if (this.debugLogView) {
this.debugLogView.remove();
this.debugLogView = null;
}
},
onClickExport: function() {
this.error = null;
if (!Whisper.Migration.everComplete()) {
return this.beginMigration();
}
// Different behavior for the user's second time through
Whisper.Migration.beginExport()
.then(this.completeMigration.bind(this))
.catch(function(error) {
if (error.name !== 'ChooseError') {
this.error = error.message;
}
// Even if we run into an error, we call this complete because the user has
// completed the process once before.
Whisper.Migration.markComplete();
this.render();
}.bind(this));
this.render();
},
beginMigration: function() {
Whisper.events.once('shutdown-complete', function() {
Whisper.Migration.beginExport()
.then(this.completeMigration.bind(this))
.catch(this.onError.bind(this));
// Rendering because we're now in the 'exporting' state
this.render();
}.bind(this));
// tells MessageReceiver to disconnect and drain its queue, will fire
// 'shutdown-complete' event when that is done. Might result in a synchronous
// event, so call it after we register our callback.
Whisper.Migration.init();
// Rendering because we're now in the 'disconnected' state
this.render();
},
completeMigration: function(target) {
// This will prevent connection to the server on future app launches
Whisper.Migration.markComplete(target);
this.render();
},
onError: function(error) {
if (error.name === 'ChooseError') {
this.cancelMigration();
} else {
Whisper.Migration.cancel();
this.error = error.message;
this.render();
}
},
cancelMigration: function() {
Whisper.Migration.cancel();
this.render();
}
});
}());