blob: af93d9d83dcd7b2f33967543046206eab8b2a07f [file] [log] [blame]
<!-- The <detail-list2-sk> custom element declaration.
Manages a list of child elements like digest-detail-sk that produce
zoom-clicked, triage and commit-info events.
Handles the events and also focus highlighting. It also responds to
keyboard shortcuts. Since keyboard events are registered against the
global 'document' object, it provides the 'startUse' and 'endUse'
functions to indicate when this element is active. This is particularly
important if it's part of dynamic behavior like pop-up dialogs.
Attributes:
data - Takes a search.NewSearchResponse describing search results to be
displayed.
Events:
None
Methods:
startUse - to be called before the element is atively being used.
It registers the necessary keyboard shortcuts.
endUse - to be called once the element is not used any more.
openHelpDialog - opens the help dialog for key bindings.
-->
<link rel="import" href="digest-details2-sk.html">
<link rel="import" href="zoom-dialog-sk.html">
<link rel="import" href="help-dialog-sk.html">
<dom-module id="detail-list2-sk">
<style type="text/css" media="screen">
digest-details2-sk {
display: block;
box-shadow: 3px 3px 6px 1px rgba(133,133,133,1);
margin-top: 1em;
margin-bottom: 1em;
margin-left: 0;
margin-right: 0;
padding-left: 1em;
padding-top: 1em;
padding-bottom: 1em;
padding-right: 0;
}
paper-button {
background: #1F78B4;
color: white;
}
#indexStatus {
font-weight: bold;
font-size: 130%;
margin-left: 2em;
}
</style>
<template>
<div>
<paper-button on-tap=_focusFirst title="&lt;" disabled$="[[_isFirst(_index)]]" raised>|&lt;</paper-button>
<paper-button on-tap=_focusPrev title="k" disabled$="[[_isFirst(_index)]]" raised>Prev</paper-button>
<paper-button on-tap=_focusNext title="j" disabled$="[[_isLast(_index)]]" raised>Next</paper-button>
<paper-button on-tap=_focusLast title="&gt;" disabled$="[[_isLast(_index)]]" raised>&gt;|</paper-button>
<span id=indexStatus>Digest: [[_plusone(_index)]]/[[data.size]]</span>
</div>
<digest-details2-sk
id="digestdetails"
mode="list"
triage
details="[[_item]]"
commits="[[data.commits]]"
issue="[[data.issue.id]]">
</digest-details2-sk>
<!-- zoom dialog -->
<zoom-dialog-sk id="detailsZoomDialog"></zoom-dialog-sk>
<!-- help dialog -->
<help-dialog-sk id="helpDialog">
<table>
<tr><th colspan=2>Keyboard Shortcuts</th></tr>
<tr><th>J</th><td>Next</td></tr>
<tr><th>K</th><td>Prev</td></tr>
<tr><th>&lt;</th><td>First</td></tr>
<tr><th>&gt;</th><td>Last</td></tr>
<tr><th>W</th><td>Zoom</td></tr>
<tr><th>A</th><td>Postive</td></tr>
<tr><th>S</th><td>Negative</td></tr>
<tr><th>D</th><td>Untriaged</td></tr>
<tr><th>?</th><td>Help</td></tr>
</table>
</help-dialog-sk>
</template>
<script>
Polymer({
is: 'detail-list2-sk',
properties: {
data: {
type: Object,
value: function() {
return {
digests: [],
commits: [],
issue: null,
offset: 0,
size: 0,
}
},
reflectToAttribute: false,
observer: "_dataChange",
},
_item: {
type: Object,
value: null,
reflectToAttribute: false,
},
},
ready: function () {
this._zooming = false;
this._index = 0;
this.listen(this, 'zoom-clicked', "_handleZoomClicked");
this.listen(this, 'iron-overlay-closed', '_handleZoomClosed');
this.listen(this, 'triage', '_handleTriage');
},
startUse: function() {
this.listen(document, 'keypress', '_handleKeyDown');
},
endUse: function() {
this.unlisten(document, 'keypress', '_handleKeyDown');
},
openHelpDialog: function() {
this.$.helpDialog.open();
},
_dataChange: function() {
this._index = 0;
if (!this.data || !this.data.digests || this.data.digests.length === 0) {
return
}
this.set('_item', this.data.digests[0]);
},
_handleKeyDown: function(e) {
if (this._zooming) {
return;
}
var c = String.fromCharCode(e.keyCode).toUpperCase();
switch (c) {
case 'J':
this._focusNext();
break;
case 'K':
this._focusPrev();
break;
case '<':
this._focusFirst();
break;
case '>':
this._focusLast();
break;
case 'A':
this._markFocus('positive');
break;
case 'S':
this._markFocus('negative');
break;
case 'D':
this._markFocus('untriaged');
break;
case 'W':
this._handleZoomClicked();
break;
case '?':
this.openHelpDialog();
break;
}
},
_handleZoomClosed: function (ev) {
this._zooming = false;
},
_handleZoomClicked: function (ev) {
var zoomDetail;
// This was triggerd by a keyboard shortcut.
if (!ev) {
var ele = this._findFocus();
if (ele == null) {
return
}
// Extract the zoom information from the element.
zoomDetail = ele.getZoomDetail();
} else {
zoomDetail = ev.detail;
ev.stopPropagation();
}
this.$.detailsZoomDialog.open(zoomDetail);
this._zooming = true;
},
_handleTriage: function (ev) {
sk.post('/json/triage', JSON.stringify(ev.detail)).catch(sk.errorMessage);
},
// _findFocus returns the current details element with the keyboard focus.
_findFocus: function () {
return this.$.digestdetails;
},
// Move the focus to the next digest.
_focusNext: function () {
if (this.data.digests.length === 0) {
return
}
this._index = this._index+1;
if (this._index >= this.data.digests.length) {
this._index = this.data.digests.length-1
}
this.set('_item', this.data.digests[this._index]);
},
// Move the focus to the previous digest.
_focusPrev: function () {
if (this.data.digests.length === 0) {
return
}
this._index = this._index-1;
if (this._index < 0) {
this._index = 0;
}
this.set('_item', this.data.digests[this._index]);
},
_focusFirst: function () {
if (this.data.digests.length === 0) {
return
}
this._index = 0;
this.set('_item', this.data.digests[this._index]);
},
_focusLast: function () {
if (this.data.digests.length === 0) {
return
}
this._index = this.data.digests.length-1;
this.set('_item', this.data.digests[this._index]);
},
_markFocus: function (status) {
var ele = this._findFocus();
if (ele && ele.triggerTriage) {
ele.triggerTriage(status);
}
},
_plusone: function(index) {
return index+1;
},
_isFirst: function(index) {
return index === 0;
},
_isLast: function(index) {
if (this.data.digests) {
return index === this.data.digests.length-1;
}
return true;
},
});
</script>
</dom-module>