You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
	
	
		
			195 lines
		
	
	
		
			5.7 KiB
		
	
	
	
		
			JavaScript
		
	
			
		
		
	
	
			195 lines
		
	
	
		
			5.7 KiB
		
	
	
	
		
			JavaScript
		
	
/*
 | 
						|
 * vim: ts=4:sw=4:expandtab
 | 
						|
 */
 | 
						|
(function () {
 | 
						|
  'use strict';
 | 
						|
  window.Whisper = window.Whisper || {};
 | 
						|
 | 
						|
  var State = {
 | 
						|
    IMPORTING: 1,
 | 
						|
    COMPLETE: 2,
 | 
						|
    LIGHT_COMPLETE: 3,
 | 
						|
  };
 | 
						|
 | 
						|
  var IMPORT_STARTED = 'importStarted';
 | 
						|
  var IMPORT_COMPLETE = 'importComplete';
 | 
						|
  var IMPORT_LOCATION = 'importLocation';
 | 
						|
 | 
						|
  Whisper.Import = {
 | 
						|
    isStarted: function() {
 | 
						|
      return Boolean(storage.get(IMPORT_STARTED));
 | 
						|
    },
 | 
						|
    isComplete: function() {
 | 
						|
      return Boolean(storage.get(IMPORT_COMPLETE));
 | 
						|
    },
 | 
						|
    isIncomplete: function() {
 | 
						|
      return this.isStarted() && !this.isComplete();
 | 
						|
    },
 | 
						|
    start: function() {
 | 
						|
      return storage.put(IMPORT_STARTED, true);
 | 
						|
    },
 | 
						|
    complete: function() {
 | 
						|
      return storage.put(IMPORT_COMPLETE, true);
 | 
						|
    },
 | 
						|
    saveLocation: function(location) {
 | 
						|
      return storage.put(IMPORT_LOCATION, location);
 | 
						|
    },
 | 
						|
    reset: function() {
 | 
						|
      return Whisper.Database.clear();
 | 
						|
    }
 | 
						|
  };
 | 
						|
 | 
						|
  Whisper.ImportView = Whisper.View.extend({
 | 
						|
    templateName: 'import-flow-template',
 | 
						|
    className: 'full-screen-flow',
 | 
						|
    events: {
 | 
						|
      'click .choose': 'onImport',
 | 
						|
      'click .restart': 'onRestart',
 | 
						|
      'click .cancel': 'onCancel',
 | 
						|
      'click .register': 'onRegister',
 | 
						|
    },
 | 
						|
    initialize: function() {
 | 
						|
      if (Whisper.Import.isIncomplete()) {
 | 
						|
        this.error = true;
 | 
						|
      }
 | 
						|
 | 
						|
      this.render();
 | 
						|
      this.pending = Promise.resolve();
 | 
						|
    },
 | 
						|
    render_attributes: function() {
 | 
						|
      if (this.error) {
 | 
						|
        return {
 | 
						|
          isError: true,
 | 
						|
          errorHeader: i18n('importErrorHeader'),
 | 
						|
          errorMessage: i18n('importError'),
 | 
						|
          chooseButton: i18n('importAgain'),
 | 
						|
        };
 | 
						|
      }
 | 
						|
 | 
						|
      var restartButton = i18n('importCompleteStartButton');
 | 
						|
      var registerButton = i18n('importCompleteLinkButton');
 | 
						|
      var step = 'step2';
 | 
						|
 | 
						|
      if (this.state === State.IMPORTING) {
 | 
						|
        step = 'step3';
 | 
						|
      } else if (this.state === State.COMPLETE) {
 | 
						|
        registerButton = null;
 | 
						|
        step = 'step4';
 | 
						|
      } else if (this.state === State.LIGHT_COMPLETE) {
 | 
						|
        restartButton = null;
 | 
						|
        step = 'step4';
 | 
						|
      }
 | 
						|
 | 
						|
      return {
 | 
						|
        isStep2: step === 'step2',
 | 
						|
        chooseHeader: i18n('loadDataHeader'),
 | 
						|
        choose: i18n('loadDataDescription'),
 | 
						|
        chooseButton: i18n('chooseDirectory'),
 | 
						|
 | 
						|
        isStep3: step === 'step3',
 | 
						|
        importingHeader: i18n('importingHeader'),
 | 
						|
 | 
						|
        isStep4: step === 'step4',
 | 
						|
        completeHeader: i18n('importCompleteHeader'),
 | 
						|
        restartButton: restartButton,
 | 
						|
        registerButton: registerButton,
 | 
						|
      };
 | 
						|
    },
 | 
						|
    onRestart: function() {
 | 
						|
      return window.restart();
 | 
						|
    },
 | 
						|
    onCancel: function() {
 | 
						|
      this.trigger('cancel');
 | 
						|
    },
 | 
						|
    onImport: function() {
 | 
						|
      window.Signal.Backup.getDirectoryForImport().then(function(directory) {
 | 
						|
        this.doImport(directory);
 | 
						|
      }.bind(this), function(error) {
 | 
						|
        if (error.name !== 'ChooseError') {
 | 
						|
          console.log(
 | 
						|
            'Error choosing directory:',
 | 
						|
            error && error.stack ? error.stack : error
 | 
						|
          );
 | 
						|
        }
 | 
						|
      });
 | 
						|
    },
 | 
						|
    onRegister: function() {
 | 
						|
      // AppView listens for this, and opens up InstallView to the QR code step to
 | 
						|
      //   finish setting this device up.
 | 
						|
      this.trigger('light-import');
 | 
						|
    },
 | 
						|
 | 
						|
    doImport: function(directory) {
 | 
						|
      window.removeSetupMenuItems();
 | 
						|
 | 
						|
      this.error = null;
 | 
						|
      this.state = State.IMPORTING;
 | 
						|
      this.render();
 | 
						|
 | 
						|
      // Wait for prior database interaction to complete
 | 
						|
      this.pending = this.pending.then(function() {
 | 
						|
        // For resilience to interruption, clear database both before and on failure
 | 
						|
        return Whisper.Import.reset();
 | 
						|
      }).then(function() {
 | 
						|
        return Promise.all([
 | 
						|
          Whisper.Import.start(),
 | 
						|
          window.Signal.Backup.importFromDirectory(directory)
 | 
						|
        ]);
 | 
						|
      }).then(function(results) {
 | 
						|
        var importResult = results[1];
 | 
						|
 | 
						|
        // A full import changes so much we need a restart of the app
 | 
						|
        if (importResult.fullImport) {
 | 
						|
          return this.finishFullImport(directory);
 | 
						|
        }
 | 
						|
 | 
						|
        // A light import just brings in contacts, groups, and messages. And we need a
 | 
						|
        //   normal link to finish the process.
 | 
						|
        return this.finishLightImport(directory);
 | 
						|
      }.bind(this)).catch(function(error) {
 | 
						|
        console.log('Error importing:', error && error.stack ? error.stack : error);
 | 
						|
 | 
						|
        this.error = error || new Error('Something went wrong!');
 | 
						|
        this.state = null;
 | 
						|
        this.render();
 | 
						|
 | 
						|
        return Whisper.Import.reset();
 | 
						|
      }.bind(this));
 | 
						|
    },
 | 
						|
    finishLightImport: function(directory) {
 | 
						|
      ConversationController.reset();
 | 
						|
 | 
						|
      return ConversationController.load().then(function() {
 | 
						|
        return Promise.all([
 | 
						|
            Whisper.Import.saveLocation(directory),
 | 
						|
            Whisper.Import.complete(),
 | 
						|
          ]);
 | 
						|
      }).then(function() {
 | 
						|
        this.state = State.LIGHT_COMPLETE;
 | 
						|
        this.render();
 | 
						|
      }.bind(this));
 | 
						|
    },
 | 
						|
    finishFullImport: function(directory) {
 | 
						|
      // Catching in-memory cache up with what's in indexeddb now...
 | 
						|
      // NOTE: this fires storage.onready, listened to across the app. We'll restart
 | 
						|
      //   to complete the install to start up cleanly with everything now in the DB.
 | 
						|
      return storage.fetch()
 | 
						|
        .then(function() {
 | 
						|
          return Promise.all([
 | 
						|
            // Clearing any migration-related state inherited from the Chrome App
 | 
						|
            storage.remove('migrationState'),
 | 
						|
            storage.remove('migrationEnabled'),
 | 
						|
            storage.remove('migrationEverCompleted'),
 | 
						|
            storage.remove('migrationStorageLocation'),
 | 
						|
 | 
						|
            Whisper.Import.saveLocation(directory),
 | 
						|
            Whisper.Import.complete()
 | 
						|
          ]);
 | 
						|
        }).then(function() {
 | 
						|
          this.state = State.COMPLETE;
 | 
						|
          this.render();
 | 
						|
        }.bind(this));
 | 
						|
    }
 | 
						|
  });
 | 
						|
})();
 |