Update the selected file in change view after nav in diff view

+ Share change view state with the diff view to allow changing of
  the selected file index.
+ Remove sessionStorage use case in favor of using change view
  state.
+ Implement [ and ] keyboard shortcuts in change view.

Bug: Issue 3857
Change-Id: Ib6ea751a7e6489012f23727ef69e44923e848704
This commit is contained in:
Andrew Bonventre 2016-02-03 20:40:36 -08:00
parent 6eb93e58b1
commit 4a8fff2707
5 changed files with 56 additions and 16 deletions

View File

@ -99,20 +99,27 @@ limitations under the License.
</header>
<main>
<template is="dom-if" if="{{_showChangeListView}}" restamp="true">
<gr-change-list-view params="[[params]]"
<gr-change-list-view
params="[[params]]"
view-state="{{_viewState.changeListView}}"
logged-in="[[_computeLoggedIn(account)]]"></gr-change-list-view>
</template>
<template is="dom-if" if="{{_showDashboardView}}" restamp="true">
<gr-dashboard-view params="[[params]]"
<gr-dashboard-view
params="[[params]]"
view-state="{{_viewState.dashboardView}}"></gr-dashboard-view>
</template>
<template is="dom-if" if="{{_showChangeView}}" restamp="true">
<gr-change-view server-config="[[config]]"
params="[[params]]" view-state="{{_viewState.changeView}}"></gr-change-view>
<gr-change-view
params="[[params]]"
server-config="[[config]]"
view-state="{{_viewState.changeView}}"></gr-change-view>
</template>
<template is="dom-if" if="{{_showDiffView}}" restamp="true">
<gr-diff-view prefs="{{_diffPreferences}}" params="[[params]]"></gr-diff-view>
<gr-diff-view
params="[[params]]"
prefs="{{_diffPreferences}}"
change-view-state="{{_viewState.changeView}}"></gr-diff-view>
</template>
</main>
<footer role="contentinfo">
@ -196,6 +203,7 @@ limitations under the License.
changeNum: null,
patchNum: null,
selectedFileIndex: 0,
showReplyDropdown: false,
},
changeListView: {
query: null,

View File

@ -418,9 +418,9 @@ limitations under the License.
app.accountReady.then(function() {
if (!this._loggedIn) { return; }
if (window.sessionStorage.getItem('changeView.showReplyDropdown')) {
if (this.viewState.showReplyDropdown) {
this.$.replyDropdown.open();
window.sessionStorage.removeItem('changeView.showReplyDropdown');
this.set('viewState.showReplyDropdown', false);
}
}.bind(this));
}.bind(this));

View File

@ -155,6 +155,11 @@ limitations under the License.
type: Object,
value: function() { return document.body; },
},
changeViewState: {
type: Object,
notify: true,
value: function() { return {}; },
},
_patchRange: Object,
_change: Object,
@ -164,7 +169,10 @@ limitations under the License.
type: Array,
value: function() { return []; },
},
_path: String,
_path: {
type: String,
observer: '_pathChanged',
},
_loggedIn: {
type: Boolean,
value: false,
@ -208,9 +216,7 @@ limitations under the License.
case 65: // 'a'
if (!this._loggedIn) { return; }
// Values can only be strings.
window.sessionStorage.setItem(
'changeView.showReplyDropdown', 'true');
this.set('changeViewState.showReplyDropdown', true);
// No break here. Allow to fall through.
case 85: // 'u'
if (this._changeNum) {
@ -266,6 +272,13 @@ limitations under the License.
this.$.diff.reload();
},
_pathChanged: function(path) {
if (this._fileList.length == 0) { return; }
this.set('changeViewState.selectedFileIndex',
this._fileList.indexOf(path));
},
_computeDiffURL: function(changeNum, patchRange, path) {
var patchStr = patchRange.patchNum;
if (patchRange.basePatchNum != null &&

View File

@ -191,15 +191,30 @@ limitations under the License.
e.preventDefault();
this.selectedIndex = Math.max(0, this.selectedIndex - 1);
break;
case 219: // '['
e.preventDefault();
this._openSelectedFile(this.files.length - 1);
break;
case 221: // ']'
e.preventDefault();
this._openSelectedFile(0);
break;
case 13: // <enter>
case 79: // 'o'
e.preventDefault();
page(this._computeDiffURL(this.changeNum, this.patchNum,
this.files[this.selectedIndex].__path));
this._openSelectedFile();
break;
}
},
_openSelectedFile: function(opt_index) {
if (opt_index != null) {
this.selectedIndex = opt_index;
}
page(this._computeDiffURL(this.changeNum, this.patchNum,
this.files[this.selectedIndex].__path));
},
_computeFileSelected: function(index, selectedIndex) {
return index == selectedIndex;
},

View File

@ -52,6 +52,7 @@ limitations under the License.
};
element._fileList = ['chell.go', 'glados.txt', 'wheatley.md'];
element._path = 'glados.txt';
element.changeViewState.selectedFileIndex = 1;
var showStub = sinon.stub(page, 'show');
MockInteractions.pressAndReleaseKeyOn(element, 85); // 'u'
@ -62,20 +63,24 @@ limitations under the License.
assert(showStub.lastCall.calledWithExactly('/c/42/10/wheatley.md'),
'Should navigate to /c/42/10/wheatley.md');
element._path = 'wheatley.md';
assert.equal(element.changeViewState.selectedFileIndex, 2);
MockInteractions.pressAndReleaseKeyOn(element, 219); // '['
assert(showStub.lastCall.calledWithExactly('/c/42/10/glados.txt'),
'Should navigate to /c/42/10/glados.txt');
element._path = 'glados.txt';
assert.equal(element.changeViewState.selectedFileIndex, 1);
MockInteractions.pressAndReleaseKeyOn(element, 219); // '['
assert(showStub.lastCall.calledWithExactly('/c/42/10/chell.go'),
'Should navigate to /c/42/10/chell.go');
element._path = 'chell.go';
assert.equal(element.changeViewState.selectedFileIndex, 0);
MockInteractions.pressAndReleaseKeyOn(element, 219); // '['
assert(showStub.lastCall.calledWithExactly('/c/42'),
'Should navigate to /c/42');
assert.equal(element.changeViewState.selectedFileIndex, 0);
var showPrefsStub = sinon.stub(element.$.diff, 'showDiffPreferences');
MockInteractions.pressAndReleaseKeyOn(element, 188); // ','
@ -104,9 +109,8 @@ limitations under the License.
element._loggedIn = true;
MockInteractions.pressAndReleaseKeyOn(element, 65); // 'a'
assert.equal(window.sessionStorage.getItem(
'changeView.showReplyDropdown'), 'true');
window.sessionStorage.removeItem('changeView.showReplyDropdown');
assert.isTrue(element.changeViewState.showReplyDropdown);
assert(showStub.lastCall.calledWithExactly('/c/42'),
'Should navigate to /c/42');