playground/client: add temporary error rendering.

While vanadium/issues#294 is unresolved the client will display
a nice error message so that the TOS links and content can somewhat be
reviewed ahead of launch.

Change-Id: Ieb59f157782edf2eb1e2b9c29965dae2330771cb
diff --git a/client/Makefile b/client/Makefile
index d2267e9..000aab9 100644
--- a/client/Makefile
+++ b/client/Makefile
@@ -18,8 +18,7 @@
 .PHONY: deploy-staging
 deploy-staging: all
 	git rev-parse --verify HEAD > public/version
-	gcloud config set project vanadium-staging
-	gsutil -m rsync -d -r public gs://playground.staging.v.io
+	gsutil rsync -c -d -r public gs://playground.staging.v.io
 
 public/bundle.js: browser/index.js $(js_files) node_modules
 	browserify --debug $< 1> $@
diff --git a/client/browser/api/index.js b/client/browser/api/index.js
index c2e5d6b..c8f74c6 100644
--- a/client/browser/api/index.js
+++ b/client/browser/api/index.js
@@ -19,7 +19,7 @@
   timeout: 5 * 60 * 1000,
   // Temporarily default to the staging load balancer until bundle lists are
   // available from the API.
-  url: 'http://104.197.24.229:8181/',
+  url: 'https://playground-api.v.io',
   debug: false
 };
 
@@ -203,7 +203,7 @@
 // TODO(jasoncampbell): Drop the callback API and return the stream
 // immediately.
 // TODO(jasoncampbell): stop pending xhr
-// SEE: https://github.com/veyron/release-issues/issues/1890
+// SEE: https://github.com/vanadium/issues/issues/39
 API.prototype.run = function(data, callback) {
   var api = this;
   var uuid = data.uuid;
diff --git a/client/browser/components/bundle/index.js b/client/browser/components/bundle/index.js
index d8885f4..ac85a98 100644
--- a/client/browser/components/bundle/index.js
+++ b/client/browser/components/bundle/index.js
@@ -91,7 +91,7 @@
     if (err) {
       // TODO(jasoncampbell): handle error appropriately.
       //
-      // SEE: https://github.com/veyron/release-issues/issues/1890
+      // SEE: https://github.com/vanadium/issues/issues/39
       throw err;
     }
 
diff --git a/client/browser/components/bundle/render.js b/client/browser/components/bundle/render.js
index 615d49a..746d1f8 100644
--- a/client/browser/components/bundle/render.js
+++ b/client/browser/components/bundle/render.js
@@ -20,7 +20,9 @@
   // NOTE: It is possible to try and render a bundle without it being
   // populated from the API yet. In that case show a loader.
   if (! state) {
-    return h('.bundle', 'Loading...');
+    return h('.bundle', [
+      h('p.loading', 'Loading...')
+    ]);
   }
 
   return h('.bundle', [
diff --git a/client/browser/components/bundles/render.js b/client/browser/components/bundles/render.js
index 3349a00..8f7dd99 100644
--- a/client/browser/components/bundles/render.js
+++ b/client/browser/components/bundles/render.js
@@ -15,7 +15,7 @@
   var bundles = toArray(state);
 
   if (bundles.length === 0) {
-    return h('p', 'Loading...');
+    return h('p.loading', 'Loading...');
   } else {
     return h('ul.bundles', bundles.map(li));
   }
diff --git a/client/browser/components/error/index.js b/client/browser/components/error/index.js
new file mode 100644
index 0000000..cc6c5e7
--- /dev/null
+++ b/client/browser/components/error/index.js
@@ -0,0 +1,27 @@
+// 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 hg = require('mercury');
+var assert = require('assert');
+
+module.exports = error;
+module.exports.render = require('./render');
+
+// A temporary way to display errors meaningfully to the user while logging
+// relevant bits to the developer console.
+function error(data) {
+  assert.ok(data.error, 'data.error is required');
+  assert.ok(data.error instanceof Error, 'data.error must be an error');
+
+  var state = hg.state({
+    title: data.title || data.error.name,
+    body: data.body || data.error.message,
+    error: data.error
+  });
+
+  console.error('Error reported via components/error');
+  console.error(data.error.stack);
+
+  return state;
+}
diff --git a/client/browser/components/error/render.js b/client/browser/components/error/render.js
new file mode 100644
index 0000000..45ced12
--- /dev/null
+++ b/client/browser/components/error/render.js
@@ -0,0 +1,14 @@
+// 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 h = require('mercury').h;
+
+module.exports = render;
+
+function render(state) {
+  return h('.error', [
+    h('h1', state.title),
+    h('p', state.body)
+  ]);
+}
diff --git a/client/browser/index.js b/client/browser/index.js
index e89d822..7476ad5 100644
--- a/client/browser/index.js
+++ b/client/browser/index.js
@@ -12,6 +12,7 @@
 var bundle = require('./components/bundle');
 var bundles = require('./components/bundles');
 var toast = require('./components/toast');
+var error = require('./components/error');
 var api = require('./api');
 
 // Make the debug module accessible via the console. This allows the module's
@@ -34,7 +35,8 @@
     bundles: bundles(),
     uuid: hg.value(''),
     toast: toast(),
-    title: hg.value('Vanadium Playground')
+    title: hg.value('Vanadium Playground'),
+    error: hg.value(null)
   });
 
   router({
@@ -51,7 +53,14 @@
 
     api.bundles(function(err, list) {
       if (err) {
-        return console.error('TODO: API list error', err);
+        state.error.set(error({
+          title: 'API Error',
+          body: 'There was problem retrieving the list of examples. ' +
+            'Please try again later.',
+          error: err
+        }));
+
+        return;
       }
 
       var length = list.length;
@@ -70,7 +79,7 @@
     // TODO(jasoncampbell): If there is not an entry for `params.uuid` show a
     // spinner/loader.
     //
-    // SEE: https://github.com/veyron/release-issues/issues/1890
+    // SEE: https://github.com/vanadium/issues/issues/39
 
     api.get(params.uuid, function(err, data) {
       if (err) {
@@ -82,7 +91,7 @@
     });
   }
 
-  // SEE: https://github.com/veyron/release-issues/issues/1890
+  // SEE: https://github.com/vanadium/issues/issues/39
   function notfound(href) {
     console.error('TODO: not found error - %s', href);
   }
diff --git a/client/browser/render.js b/client/browser/render.js
index 303e751..6535416 100644
--- a/client/browser/render.js
+++ b/client/browser/render.js
@@ -8,6 +8,7 @@
 var header = require('./components/header');
 var bundles = require('./components/bundles');
 var bundle = require('./components/bundle');
+var error = require('./components/error');
 
 module.exports = render;
 
@@ -44,6 +45,9 @@
       state.bundles[state.uuid],
       state.channels
     );
+  } else if (state.error) {
+    // Temporary error rendering until vanadium/issues#294 is resolved.
+    partial = hg.partial(error.render, state.error);
   } else {
     // By default show a list of bundles
     partial = hg.partial(bundles.render, state.bundles);
diff --git a/client/package.json b/client/package.json
index 175cdbd..bd88b80 100644
--- a/client/package.json
+++ b/client/package.json
@@ -4,7 +4,7 @@
   "description": "Vanadium playground web client",
   "version": "0.0.0",
   "bugs": {
-    "url": "https://github.com/veyron/release-issues/issues"
+    "url": "https://github.com/vanadium/issues/issues"
   },
   "main": "browser/index.js",
   "dependencies": {
diff --git a/client/stylesheets/index.css b/client/stylesheets/index.css
index 93be513..80bea7d 100644
--- a/client/stylesheets/index.css
+++ b/client/stylesheets/index.css
@@ -163,3 +163,20 @@
 .console.debug .log.debug {
   display: block;
 }
+
+.error {
+  margin: var(--gutter) auto;
+  padding: var(--gutter);
+}
+
+.error .details {
+  border: 4px solid red;
+}
+
+.error .details.hide {
+  border: 4px solid green;
+}
+
+.loading {
+  margin: var(--gutter) auto;
+}
diff --git a/pgbundle/package.json b/pgbundle/package.json
index dd49453..9fc00e0 100644
--- a/pgbundle/package.json
+++ b/pgbundle/package.json
@@ -5,7 +5,7 @@
   "version": "0.0.1",
   "bin": "./bin/pgbundle",
   "bugs": {
-    "url": "https://github.com/veyron/release-issues/issues"
+    "url": "https://github.com/vanadium/issues/issues"
   },
   "dependencies": {
     "glob": "^4.3.5",