Merge "nsb: Ensure that namespace is set from app load"
diff --git a/src/app.js b/src/app.js
index f8e66a7..795c0d3 100644
--- a/src/app.js
+++ b/src/app.js
@@ -16,6 +16,7 @@
 var viewport = require('./components/viewport/index');
 var userAccount = require('./components/user-account/index');
 var namespaceService = require('./services/namespace/service');
+var stateService = require('./services/state/service');
 var errorRoute = require('./routes/error');
 
 var browseComponent = browse();
@@ -117,14 +118,17 @@
 // Wire Events
 wireEvents();
 
-// Start the router which will register the application routes
-router(state, events);
-
 // Register the plugins
 registerItemPlugins();
 
-// Initialize Vanadium
-initVanadium();
+// Load the user's saved state, followed by other dependencies.
+loadUserState().then(function() {
+  // Start the router which will register the application routes
+  router(state, events);
+
+  // Initialize Vanadium
+  initVanadium();
+});
 
 // Debugging related exports
 exportDebugging();
@@ -184,6 +188,22 @@
 }
 
 /*
+ * Load any of the user's application state.
+ * Note: This promise will always resolve.
+ */
+function loadUserState() {
+  var loads = [];
+
+  // Set the initial namespace for the user. This guarantees that regardless
+  // of starting route, that the user continues where they last left off.
+  loads.push(stateService.loadNamespace().then(function(namespace) {
+    state.browse.namespace.set(namespace);
+  }));
+
+  return Promise.all(loads).catch(function() {});
+}
+
+/*
  * Initialized vanadium and sets appropriate messages on the splash screen
  */
 function initVanadium() {
@@ -191,10 +211,11 @@
   namespaceService.initVanadium().then(function(vruntime) {
     vruntime.once('crash', onVanadiumCrash);
     viewport.setSplashMessage('Initialized');
-    state.initialized.set(true);
 
-    // Onboarding Hook for new users after Vanadium is initialized.
+    // Onboarding Hook for new users (async). Currently does not block.
     onboarding(vruntime, state);
+
+    state.initialized.set(true);
   }).catch(function(err) {
     if (err instanceof vanadium.verror.ExtensionNotInstalledError) {
       vanadium.extension.promptUserToInstallExtension();
diff --git a/src/routes/browse.js b/src/routes/browse.js
index 61118f3..58b1b44 100644
--- a/src/routes/browse.js
+++ b/src/routes/browse.js
@@ -6,9 +6,7 @@
 var qsUtil = require('querystring');
 
 var exists = require('../lib/exists');
-var store = require('../lib/store');
-
-var log = require('../lib/log')('routes:browse');
+var stateService = require('../services/state/service');
 
 module.exports = function(routes) {
   // Url pattern: /browse/vanadiumNameSpace?glob=*&viewType=grid
@@ -70,10 +68,8 @@
     }
   }
 
-  // Put the URL in the store, so we know where to reload next time.
-  store.setValue('index', namespace).catch(function(err) {
-    log.warn('Unable to save last name visited', err);
-  });
+  // Persist this namespace so that we know where to reload next time.
+  stateService.saveNamespace(namespace);
 
   // Trigger browse components browseNamespace event
   events.browse.browseNamespace({
diff --git a/src/routes/error.js b/src/routes/error.js
index a519dc1..22ba7ae 100644
--- a/src/routes/error.js
+++ b/src/routes/error.js
@@ -12,7 +12,7 @@
 
 function handleErrorRoute(state) {
 
-  // Set the page to help
+  // Set the page to error
   state.navigation.pageKey.set('error');
   state.viewport.title.set('Error');
 }
\ No newline at end of file
diff --git a/src/routes/index.js b/src/routes/index.js
index 6edee8f..1941feb 100644
--- a/src/routes/index.js
+++ b/src/routes/index.js
@@ -3,37 +3,16 @@
 // license that can be found in the LICENSE file.
 
 var browseRoute = require('./browse');
-var store = require('../lib/store');
-
-var log = require('../lib/log')('routes:index');
 
 module.exports = function(routes) {
   routes.addRoute('/', handleIndexRoute);
 };
 
 function handleIndexRoute(state, events) {
-  // TODO(aghassemi) What's the prod address?, do we even want to point to
-  // v.io by default?
-  var index = '/ns.dev.v.io:8101';
-  store.getValue('index').then(function(storedIndex) {
-    if (storedIndex) {
-      index = storedIndex;
-    }
-
-    // Redirect to browse
-    events.navigation.navigate({
-      path: browseRoute.createUrl(state.browse(), {
-        namespace: index
-      })
-    });
-  }).catch(function(err) {
-    log.warn('Unable to access stored index', err);
-
-    // Redirect to browse
-    events.navigation.navigate({
-      path: browseRoute.createUrl(state.browse(), {
-        namespace: index
-      })
-    });
+  // Send the user to the browse route with their current namespace.
+  events.navigation.navigate({
+    path: browseRoute.createUrl(state.browse(), {
+      namespace: state.browse.namespace()
+    })
   });
 }
diff --git a/src/services/state/service.js b/src/services/state/service.js
new file mode 100644
index 0000000..648ef0d
--- /dev/null
+++ b/src/services/state/service.js
@@ -0,0 +1,33 @@
+// Copyright 2015 The Vanadium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+var store = require('../../lib/store');
+
+var log = require('../../lib/log')('services:state:service');
+
+var NAMESPACE_INDEX = 'index';
+
+// TODO(alexfandrianto): Add save+load for sidePanelWidth and currentView.
+// https://github.com/vanadium/browser/issues/74
+module.exports = {
+  saveNamespace: saveNamespace,
+  loadNamespace: loadNamespace
+};
+
+function loadNamespace() {
+  // TODO(aghassemi): Do we want to point to v.io by default?
+  var index = '/ns.dev.v.io:8101';
+  return store.getValue(NAMESPACE_INDEX).then(function(namespace) {
+    return namespace || index;
+  }).catch(function(err) {
+    log.warn('Unable to access stored namespace index', err);
+    return index;
+  });
+}
+
+function saveNamespace(namespace) {
+  return store.setValue(NAMESPACE_INDEX, namespace).catch(function(err) {
+    log.warn('Unable to persist namespace index', namespace, err);
+  });
+}
\ No newline at end of file