Show comment counts in diff file dropdown

Change-Id: Ia976d7357754075b0118a85842d662f03464e7cd
diff --git a/polygerrit-ui/app/elements/diff/gr-diff-view/gr-diff-view.js b/polygerrit-ui/app/elements/diff/gr-diff-view/gr-diff-view.js
index 7c72c88..953ae1a 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff-view/gr-diff-view.js
+++ b/polygerrit-ui/app/elements/diff/gr-diff-view/gr-diff-view.js
@@ -79,7 +79,8 @@
       // element for selected a file to view.
       _formattedFiles: {
         type: Array,
-        computed: '_formatFilesForDropdown(_fileList)',
+        computed: '_formatFilesForDropdown(_fileList, _patchRange.patchNum, ' +
+            '_changeComments)',
       },
       // An sorted array of files, as returned by the rest API.
       _fileList: {
@@ -641,7 +642,7 @@
       return this._getChangePath(change, patchRangeRecord.base, revisions);
     },
 
-    _formatFilesForDropdown(fileList) {
+    _formatFilesForDropdown(fileList, patchNum, changeComments) {
       if (!fileList) { return; }
       const dropdownContent = [];
       for (const path of fileList) {
@@ -649,11 +650,29 @@
           text: this.computeDisplayPath(path),
           mobileText: this.computeTruncatedPath(path),
           value: path,
+          bottomText: this._computeCommentString(changeComments, patchNum,
+              path),
         });
       }
       return dropdownContent;
     },
 
+    _computeCommentString(changeComments, patchNum, path) {
+      const unresolvedCount = changeComments.computeUnresolvedNum(patchNum,
+          path);
+      const commentCount = changeComments.computeCommentCount(patchNum, path);
+      const commentString = GrCountStringFormatter.computePluralString(
+          commentCount, 'comment');
+      const unresolvedString = GrCountStringFormatter.computeString(
+          unresolvedCount, 'unresolved');
+
+      return commentString +
+          // Add a space if both comments and unresolved
+          (commentString && unresolvedString ? ', ' : '') +
+          // Add parentheses around unresolved if it exists.
+          (unresolvedString ? `${unresolvedString}` : '');
+    },
+
     _computePrefsButtonHidden(prefs, loggedIn) {
       return !loggedIn || !prefs;
     },
diff --git a/polygerrit-ui/app/elements/diff/gr-diff-view/gr-diff-view_test.html b/polygerrit-ui/app/elements/diff/gr-diff-view/gr-diff-view_test.html
index acb1aa5..5e23ea3 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff-view/gr-diff-view_test.html
+++ b/polygerrit-ui/app/elements/diff/gr-diff-view/gr-diff-view_test.html
@@ -315,6 +315,34 @@
       assert.isTrue(overlayOpenStub.called);
     });
 
+    test('_computeCommentString', done => {
+      loadCommentSpy = sandbox.spy(element.$.commentAPI, 'loadAll');
+      const path = '/test';
+      element.$.commentAPI.loadAll().then(comments => {
+        const commentCountStub =
+            sandbox.stub(comments, 'computeCommentCount');
+        const unresolvedCountStub =
+            sandbox.stub(comments, 'computeUnresolvedNum');
+        commentCountStub.withArgs(1, path).returns(0);
+        commentCountStub.withArgs(2, path).returns(1);
+        commentCountStub.withArgs(3, path).returns(2);
+        commentCountStub.withArgs(4, path).returns(0);
+        unresolvedCountStub.withArgs(1, path).returns(1);
+        unresolvedCountStub.withArgs(2, path).returns(0);
+        unresolvedCountStub.withArgs(3, path).returns(2);
+        unresolvedCountStub.withArgs(4, path).returns(0);
+
+        assert.equal(element._computeCommentString(comments, 1, path),
+            '1 unresolved');
+        assert.equal(element._computeCommentString(comments, 2, path),
+            '1 comment');
+        assert.equal(element._computeCommentString(comments, 3, path),
+            '2 comments, 2 unresolved');
+        assert.equal(element._computeCommentString(comments, 4, path), '');
+        done();
+      });
+    });
+
     suite('url params', () => {
       setup(() => {
         sandbox.stub(Gerrit.Nav, 'getUrlForDiff', (c, p, pn, bpn) => {
@@ -340,24 +368,29 @@
             text: 'chell.go',
             mobileText: 'chell.go',
             value: 'chell.go',
+            bottomText: '',
           }, {
             text: 'glados.txt',
             mobileText: 'glados.txt',
             value: 'glados.txt',
+            bottomText: '',
           }, {
             text: 'wheatley.md',
             mobileText: 'wheatley.md',
             value: 'wheatley.md',
+            bottomText: '',
           },
           {
             text: 'Commit message',
             mobileText: 'Commit message',
             value: '/COMMIT_MSG',
+            bottomText: '',
           },
           {
             text: 'Merge list',
             mobileText: 'Merge list',
             value: '/MERGE_LIST',
+            bottomText: '',
           },
         ];