ChangeScreen2: Display a welcome bar to new users

If the user's preferences are for the site default screen, display a
welcome bar in the header with a link to the new screen documentation.
Immediately update the user's preference to be either the old screen,
or the new screen to prevent the bar from displaying again.

For anonymous users save a "gerrit_cs2" cookie for 7 days with the
value of "0" (old screen) or "1" (new screen) when the user clicks
a link to dismiss the welcome bar.

Change-Id: Idc371732bbfa160e47075b8d01bc877a46d1b723
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/Dispatcher.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/Dispatcher.java
index b44bd3d..6d2a1d7 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/Dispatcher.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/Dispatcher.java
@@ -91,10 +91,12 @@
 import com.google.gwt.core.client.GWT;
 import com.google.gwt.core.client.RunAsyncCallback;
 import com.google.gwt.http.client.URL;
+import com.google.gwt.user.client.Cookies;
 import com.google.gwt.user.client.Window;
 import com.google.gwtorm.client.KeyUtil;
 
 public class Dispatcher {
+  public static final String COOKIE_CS2 = "gerrit_cs2";
   public static boolean changeScreen2;
 
   public static String toPatchSideBySide(final Patch.Key id) {
@@ -551,6 +553,11 @@
           .getGeneralPreferences()
           .getChangeScreen();
     }
+    String v = Cookies.getCookie(Dispatcher.COOKIE_CS2);
+    if (v != null) {
+      changeScreen2 = "1".equals(v);
+      return changeScreen2;
+    }
     if (ui == null) {
       ui = Gerrit.getConfig().getChangeScreen();
     }
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/ChangeScreen2.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/ChangeScreen2.java
index a12e6fe..4490e5a 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/ChangeScreen2.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/ChangeScreen2.java
@@ -427,6 +427,9 @@
 
     ChangeGlue.fireShowChange(changeInfo, changeInfo.revision(revision));
     startPoller();
+    if (NewChangeScreenBar.show()) {
+      add(new NewChangeScreenBar(changeId));
+    }
   }
 
   private void scrollToPath(String token) {
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/NewChangeScreenBar.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/NewChangeScreenBar.java
new file mode 100644
index 0000000..fa65514
--- /dev/null
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/NewChangeScreenBar.java
@@ -0,0 +1,105 @@
+// Copyright (C) 2013 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.gerrit.client.change;
+
+import com.google.gerrit.client.Dispatcher;
+import com.google.gerrit.client.Gerrit;
+import com.google.gerrit.client.account.AccountApi;
+import com.google.gerrit.common.PageLinks;
+import com.google.gerrit.reviewdb.client.AccountGeneralPreferences.ChangeScreen;
+import com.google.gerrit.reviewdb.client.Change;
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.core.client.JavaScriptObject;
+import com.google.gwt.dom.client.Element;
+import com.google.gwt.event.dom.client.ClickEvent;
+import com.google.gwt.uibinder.client.UiBinder;
+import com.google.gwt.uibinder.client.UiField;
+import com.google.gwt.uibinder.client.UiHandler;
+import com.google.gwt.user.client.Cookies;
+import com.google.gwt.user.client.rpc.AsyncCallback;
+import com.google.gwt.user.client.ui.Anchor;
+import com.google.gwt.user.client.ui.Composite;
+import com.google.gwt.user.client.ui.HTMLPanel;
+import com.google.gwt.user.client.ui.UIObject;
+
+import java.util.Date;
+
+/** Displays a welcome to the new change screen bar. */
+class NewChangeScreenBar extends Composite {
+  interface Binder extends UiBinder<HTMLPanel, NewChangeScreenBar> {}
+  private static final Binder uiBinder = GWT.create(Binder.class);
+
+  static boolean show() {
+    if (Gerrit.isSignedIn()) {
+      return Gerrit.getUserAccount()
+          .getGeneralPreferences()
+          .getChangeScreen() == null;
+    }
+    return Cookies.getCookie(Dispatcher.COOKIE_CS2) == null;
+  }
+
+  private final Change.Id id;
+
+  @UiField Element docs;
+  @UiField Element settings;
+  @UiField Anchor keepNew;
+  @UiField Anchor keepOld;
+
+  NewChangeScreenBar(Change.Id id) {
+    this.id = id;
+    initWidget(uiBinder.createAndBindUi(this));
+    UIObject.setVisible(docs, Gerrit.getConfig().isDocumentationAvailable());
+    UIObject.setVisible(settings, Gerrit.isSignedIn());
+  }
+
+  @UiHandler("keepOld")
+  void onKeepOld(ClickEvent e) {
+    save(ChangeScreen.OLD_UI);
+    Gerrit.display(PageLinks.toChange(id));
+  }
+
+  @UiHandler("keepNew")
+  void onKeepNew(ClickEvent e) {
+    save(ChangeScreen.CHANGE_SCREEN2);
+  }
+
+  private void save(ChangeScreen sel) {
+    removeFromParent();
+    Dispatcher.changeScreen2 = sel == ChangeScreen.CHANGE_SCREEN2;
+
+    if (Gerrit.isSignedIn()) {
+      Gerrit.getUserAccount().getGeneralPreferences().setChangeScreen(sel);
+
+      Prefs in = Prefs.createObject().cast();
+      in.change_screen(sel.name());
+      AccountApi.self().view("preferences").background().post(in,
+        new AsyncCallback<JavaScriptObject>() {
+          @Override public void onFailure(Throwable caught) {}
+          @Override public void onSuccess(JavaScriptObject result) {}
+        });
+    } else {
+      Cookies.setCookie(
+        Dispatcher.COOKIE_CS2,
+        Dispatcher.changeScreen2 ? "1" : "0",
+        new Date(System.currentTimeMillis() + 7 * 24 * 3600 * 1000));
+    }
+  }
+
+  private static class Prefs extends JavaScriptObject {
+    final native void change_screen(String n) /*-{ this.change_screen=n }-*/;
+    protected Prefs() {
+    }
+  }
+}
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/NewChangeScreenBar.ui.xml b/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/NewChangeScreenBar.ui.xml
new file mode 100644
index 0000000..5df52cb
--- /dev/null
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/NewChangeScreenBar.ui.xml
@@ -0,0 +1,67 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+Copyright (C) 2013 The Android Open Source Project
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+-->
+<ui:UiBinder
+    xmlns:ui='urn:ui:com.google.gwt.uibinder'
+    xmlns:c='urn:import:com.google.gwtexpui.globalkey.client'
+    xmlns:g='urn:import:com.google.gwt.user.client.ui'>
+  <ui:style>
+    .popup {
+      position: fixed;
+      top: 5px;
+      left: 50%;
+      margin-left: -200px;
+      z-index: 201;
+      padding-top: 5px;
+      padding-bottom: 5px;
+      padding-left: 12px;
+      padding-right: 12px;
+      text-align: center;
+      background: #FFF1A8;
+      -webkit-border-radius: 10px;
+      -moz-border-radius: 10px;
+    }
+    a.action {
+      color: #222;
+      text-decoration: underline;
+      display: inline-block;
+      margin-left: 0.5em;
+    }
+    .welcome { font-weight: bold; }
+  </ui:style>
+  <g:HTMLPanel styleName='{style.popup}'>
+    <div><ui:msg><span class='{style.welcome}'>Welcome to the new change screen!</span>
+      <a ui:field='docs'
+         class='{style.action}'
+         href='Documentation/intro-change-screen.html'
+         target='_blank'>Learn more</a></ui:msg>
+    </div>
+    <div>
+      <ui:msg>You can<g:Anchor ui:field='keepOld'
+          styleName='{style.action}'
+          href='javascript:;'
+          title='Switch back to the old screen'><ui:attribute name='title'/>revert to the old screen</g:Anchor>
+      <span ui:field='settings'>in Settings &gt; Preferences</span>.
+      <g:Anchor ui:field='keepNew'
+          styleName='{style.action}'
+          href='javascript:;'
+          title='Keep the new change screen'>
+        <ui:attribute name='title'/>
+        Got it!
+      </g:Anchor></ui:msg>
+    </div>
+  </g:HTMLPanel>
+</ui:UiBinder>
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/gerrit.css b/gerrit-gwtui/src/main/java/com/google/gerrit/client/gerrit.css
index 51650c1..9a5daa8 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/gerrit.css
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/gerrit.css
@@ -371,7 +371,7 @@
   text-align: center;
   font-weight: bold;
   background: #FFF1A8;
-  z-index: 10;
+  z-index: 200;
 }
 
 
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/account/SetPreferences.java b/gerrit-server/src/main/java/com/google/gerrit/server/account/SetPreferences.java
index 33d2116..d0418eb 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/account/SetPreferences.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/account/SetPreferences.java
@@ -22,6 +22,7 @@
 import com.google.gerrit.reviewdb.client.AccountGeneralPreferences.CommentVisibilityStrategy;
 import com.google.gerrit.reviewdb.client.AccountGeneralPreferences.DateFormat;
 import com.google.gerrit.reviewdb.client.AccountGeneralPreferences.DiffView;
+import com.google.gerrit.reviewdb.client.AccountGeneralPreferences.ChangeScreen;
 import com.google.gerrit.reviewdb.client.AccountGeneralPreferences.DownloadCommand;
 import com.google.gerrit.reviewdb.client.AccountGeneralPreferences.DownloadScheme;
 import com.google.gerrit.reviewdb.client.AccountGeneralPreferences.TimeFormat;
@@ -50,6 +51,7 @@
     Boolean sizeBarInChangeTable;
     CommentVisibilityStrategy commentVisibilityStrategy;
     DiffView diffView;
+    ChangeScreen changeScreen;
   }
 
   private final Provider<CurrentUser> self;
@@ -131,6 +133,9 @@
       if (i.diffView != null) {
         p.setDiffView(i.diffView);
       }
+      if (i.changeScreen != null) {
+        p.setChangeScreen(i.changeScreen);
+      }
 
       db.accounts().update(Collections.singleton(a));
       db.commit();