Move reply from dropdown to dialog
This makes things more friendly on mobile and doesn’t have any significant usability difference. Also size the resize dialog to fit within the screen on mobile. Bug: Issue 3908 Bug: Issue 3866 Change-Id: I0aac13d47407a5f5b0d53a6efd2602d5c2b7c10c
This commit is contained in:
committed by
Dave Borowitz
parent
020c013721
commit
882043f905
@@ -238,7 +238,7 @@ limitations under the License.
|
||||
changeNum: null,
|
||||
patchNum: null,
|
||||
selectedFileIndex: 0,
|
||||
showReplyDropdown: false,
|
||||
showReplyDialog: false,
|
||||
},
|
||||
changeListView: {
|
||||
query: null,
|
||||
|
||||
@@ -39,6 +39,11 @@ limitations under the License.
|
||||
gr-button[loading]:before {
|
||||
content: attr(data-loading-label);
|
||||
}
|
||||
@media screen and (max-width: 60em) {
|
||||
.confirmDialog {
|
||||
width: 90vw;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<gr-ajax id="actionsXHR"
|
||||
url="[[_computeRevisionActionsPath(changeNum, patchNum)]]"
|
||||
|
||||
@@ -29,7 +29,7 @@ limitations under the License.
|
||||
<link rel="import" href="gr-messages-list.html">
|
||||
<link rel="import" href="gr-overlay.html">
|
||||
<link rel="import" href="gr-related-changes-list.html">
|
||||
<link rel="import" href="gr-reply-dropdown.html">
|
||||
<link rel="import" href="gr-reply-dialog.html">
|
||||
<link rel="import" href="gr-reviewer-list.html">
|
||||
|
||||
<dom-module id="gr-change-view">
|
||||
@@ -83,9 +83,12 @@ limitations under the License.
|
||||
.header select {
|
||||
margin-left: .5em;
|
||||
}
|
||||
.header gr-reply-dropdown {
|
||||
.header .reply {
|
||||
margin-left: var(--default-horizontal-margin);
|
||||
}
|
||||
gr-reply-dialog {
|
||||
width: 30em;
|
||||
}
|
||||
.changeStatus {
|
||||
color: #999;
|
||||
text-transform: capitalize;
|
||||
@@ -190,6 +193,9 @@ limitations under the License.
|
||||
justify-content: space-between;
|
||||
margin-top: .5em;
|
||||
}
|
||||
gr-reply-dialog {
|
||||
width: 90vw;
|
||||
}
|
||||
.download {
|
||||
display: none;
|
||||
}
|
||||
@@ -201,7 +207,7 @@ limitations under the License.
|
||||
margin-left: 0 !important;
|
||||
margin-right: .5em;
|
||||
}
|
||||
.header gr-reply-dropdown {
|
||||
.header .reply {
|
||||
margin-left: 0 !important;
|
||||
margin-right: .5em;
|
||||
}
|
||||
@@ -241,13 +247,7 @@ limitations under the License.
|
||||
<span class="changeStatus">[[_computeChangeStatus(_change, _patchNum)]]</span>
|
||||
</span>
|
||||
<span class="header-actions">
|
||||
<gr-reply-dropdown id="replyDropdown"
|
||||
change-num="[[_changeNum]]"
|
||||
patch-num="[[_patchNum]]"
|
||||
labels="[[_change.labels]]"
|
||||
permitted-labels="[[_change.permitted_labels]]"
|
||||
on-send="_handleReplySent"
|
||||
hidden$="[[!_loggedIn]]">Reply</gr-reply-dropdown>
|
||||
<gr-button class="reply" hidden$="[[!_loggedIn]]" hidden on-tap="_handleReplyTap">Reply</gr-button>
|
||||
<gr-button link class="download" on-tap="_handleDownloadTap">Download</gr-button>
|
||||
<span>
|
||||
<label class="patchSelectLabel" for="patchSetSelect">Patch set</label>
|
||||
@@ -363,6 +363,18 @@ limitations under the License.
|
||||
config="[[serverConfig.download]]"
|
||||
on-close="_handleDownloadDialogClose"></gr-download-dialog>
|
||||
</gr-overlay>
|
||||
<gr-overlay id="replyOverlay"
|
||||
on-iron-overlay-opened="_handleReplyOverlayOpen"
|
||||
with-backdrop>
|
||||
<gr-reply-dialog id="replyDialog"
|
||||
change-num="[[_changeNum]]"
|
||||
patch-num="[[_patchNum]]"
|
||||
labels="[[_change.labels]]"
|
||||
permitted-labels="[[_change.permitted_labels]]"
|
||||
on-send="_handleReplySent"
|
||||
on-cancel="_handleReplyCancel"
|
||||
hidden$="[[!_loggedIn]]">Reply</gr-reply-dialog>
|
||||
</gr-overlay>
|
||||
</template>
|
||||
<script>
|
||||
(function() {
|
||||
@@ -476,6 +488,11 @@ limitations under the License.
|
||||
page.show(this._computeChangePath(this._changeNum) + '/' + patchNum);
|
||||
},
|
||||
|
||||
_handleReplyTap: function(e) {
|
||||
e.preventDefault();
|
||||
this.$.replyOverlay.open();
|
||||
},
|
||||
|
||||
_handleDownloadTap: function(e) {
|
||||
e.preventDefault();
|
||||
this.$.downloadOverlay.open();
|
||||
@@ -489,14 +506,24 @@ limitations under the License.
|
||||
var msg = e.detail.message.message;
|
||||
var quoteStr = msg.split('\n').map(
|
||||
function(line) { return '> ' + line; }).join('\n') + '\n\n';
|
||||
this.$.replyDropdown.draft += quoteStr;
|
||||
this.$.replyDropdown.open();
|
||||
this.$.replyDialog.draft += quoteStr;
|
||||
this.$.replyOverlay.open();
|
||||
},
|
||||
|
||||
_handleReplyOverlayOpen: function(e) {
|
||||
this.$.replyDialog.reload();
|
||||
this.$.replyDialog.focus();
|
||||
},
|
||||
|
||||
_handleReplySent: function(e) {
|
||||
this.$.replyOverlay.close();
|
||||
this._reload();
|
||||
},
|
||||
|
||||
_handleReplyCancel: function(e) {
|
||||
this.$.replyOverlay.close();
|
||||
},
|
||||
|
||||
_paramsChanged: function(value) {
|
||||
if (value.view != this.tagName.toLowerCase()) { return; }
|
||||
|
||||
@@ -526,9 +553,9 @@ limitations under the License.
|
||||
app.accountReady.then(function() {
|
||||
if (!this._loggedIn) { return; }
|
||||
|
||||
if (this.viewState.showReplyDropdown) {
|
||||
this.$.replyDropdown.open();
|
||||
this.set('viewState.showReplyDropdown', false);
|
||||
if (this.viewState.showReplyDialog) {
|
||||
this.$.replyOverlay.open();
|
||||
this.set('viewState.showReplyDialog', false);
|
||||
}
|
||||
}.bind(this));
|
||||
}.bind(this));
|
||||
@@ -648,7 +675,7 @@ limitations under the License.
|
||||
switch (e.keyCode) {
|
||||
case 65: // 'a'
|
||||
e.preventDefault();
|
||||
this.$.replyDropdown.open();
|
||||
this.$.replyOverlay.open();
|
||||
break;
|
||||
case 85: // 'u'
|
||||
e.preventDefault();
|
||||
|
||||
@@ -278,7 +278,7 @@ limitations under the License.
|
||||
case 65: // 'a'
|
||||
if (!this._loggedIn) { return; }
|
||||
|
||||
this.set('changeViewState.showReplyDropdown', true);
|
||||
this.set('changeViewState.showReplyDialog', true);
|
||||
/* falls through */ // required by JSHint
|
||||
case 85: // 'u'
|
||||
if (this._changeNum) {
|
||||
|
||||
@@ -16,29 +16,23 @@ limitations under the License.
|
||||
|
||||
<link rel="import" href="../bower_components/polymer/polymer.html">
|
||||
<link rel="import" href="../bower_components/iron-autogrow-textarea/iron-autogrow-textarea.html">
|
||||
<link rel="import" href="../bower_components/iron-dropdown/iron-dropdown.html">
|
||||
<link rel="import" href="../bower_components/iron-selector/iron-selector.html">
|
||||
<link rel="import" href="../behaviors/rest-client-behavior.html">
|
||||
<link rel="import" href="gr-ajax.html">
|
||||
<link rel="import" href="gr-button.html">
|
||||
<link rel="import" href="gr-request.html">
|
||||
|
||||
<dom-module id="gr-reply-dropdown">
|
||||
<dom-module id="gr-reply-dialog">
|
||||
<style>
|
||||
:host {
|
||||
display: inline-block;
|
||||
display: block;
|
||||
}
|
||||
:host([disabled]) {
|
||||
pointer-events: none;
|
||||
}
|
||||
:host([disabled]) .dropdown-content {
|
||||
:host([disabled]) .container {
|
||||
opacity: .5;
|
||||
}
|
||||
iron-dropdown {
|
||||
background-color: #fff;
|
||||
box-shadow: 0 1px 5px rgba(0, 0, 0, .3);
|
||||
width: 40em;
|
||||
}
|
||||
section {
|
||||
border-top: 1px solid #ddd;
|
||||
padding: .5em .75em;
|
||||
@@ -48,6 +42,7 @@ limitations under the License.
|
||||
}
|
||||
iron-autogrow-textarea {
|
||||
padding: 0;
|
||||
font-family: var(--monospace-font-family);
|
||||
}
|
||||
.message {
|
||||
border: none;
|
||||
@@ -58,7 +53,6 @@ limitations under the License.
|
||||
}
|
||||
.labelName {
|
||||
display: inline-block;
|
||||
text-align: right;
|
||||
width: 7em;
|
||||
margin-right: .5em;
|
||||
white-space: nowrap;
|
||||
@@ -96,57 +90,51 @@ limitations under the License.
|
||||
<gr-ajax id="draftsXHR"
|
||||
url="[[_computeDraftsURL(changeNum)]]"
|
||||
last-response="{{_drafts}}"></gr-ajax>
|
||||
<gr-button id="trigger" on-tap="_showPopupTapHandler">Reply</gr-button>
|
||||
<iron-dropdown id="dropdown"
|
||||
vertical-align="top"
|
||||
vertical-offset="25"
|
||||
horizontal-align="right">
|
||||
<div class="dropdown-content">
|
||||
<section class="textareaContainer">
|
||||
<iron-autogrow-textarea
|
||||
id="textarea"
|
||||
class="message"
|
||||
placeholder="Say something..."
|
||||
disabled="{{disabled}}"
|
||||
rows="1"
|
||||
bind-value="{{draft}}"></iron-autogrow-textarea>
|
||||
</section>
|
||||
<section>
|
||||
<template is="dom-repeat"
|
||||
items="[[_computeLabelArray(permittedLabels)]]" as="label">
|
||||
<div class="labelContainer">
|
||||
<span class="labelName">[[label]]</span>
|
||||
<iron-selector data-label$="[[label]]"
|
||||
selected="[[_computeIndexOfLabelValue(labels, permittedLabels, label, _account)]]">
|
||||
<template is="dom-repeat"
|
||||
items="[[_computePermittedLabelValues(permittedLabels, label)]]"
|
||||
as="value">
|
||||
<gr-button data-value$="[[value]]">[[value]]</gr-button>
|
||||
</template>
|
||||
</iron-selector>
|
||||
</div>
|
||||
</template>
|
||||
</section>
|
||||
<section class="draftsContainer" hidden$="[[_computeHideDraftList(_drafts)]]">
|
||||
<h3>[[_computeDraftsTitle(_drafts)]]</h3>
|
||||
<gr-comment-list
|
||||
comments="[[_drafts]]"
|
||||
change-num="[[changeNum]]"
|
||||
patch-num="[[patchNum]]"></gr-comment-list>
|
||||
</section>
|
||||
<section class="actionsContainer">
|
||||
<gr-button primary class="action send" on-tap="_sendTapHandler">Send</gr-button>
|
||||
<gr-button class="action cancel" on-tap="_cancelTapHandler">Cancel</gr-button>
|
||||
</section>
|
||||
</div>
|
||||
</iron-dropdown>
|
||||
<div class="container">
|
||||
<section class="textareaContainer">
|
||||
<iron-autogrow-textarea
|
||||
id="textarea"
|
||||
class="message"
|
||||
placeholder="Say something..."
|
||||
disabled="{{disabled}}"
|
||||
rows="4"
|
||||
bind-value="{{draft}}"></iron-autogrow-textarea>
|
||||
</section>
|
||||
<section>
|
||||
<template is="dom-repeat"
|
||||
items="[[_computeLabelArray(permittedLabels)]]" as="label">
|
||||
<div class="labelContainer">
|
||||
<span class="labelName">[[label]]</span>
|
||||
<iron-selector data-label$="[[label]]"
|
||||
selected="[[_computeIndexOfLabelValue(labels, permittedLabels, label, _account)]]">
|
||||
<template is="dom-repeat"
|
||||
items="[[_computePermittedLabelValues(permittedLabels, label)]]"
|
||||
as="value">
|
||||
<gr-button data-value$="[[value]]">[[value]]</gr-button>
|
||||
</template>
|
||||
</iron-selector>
|
||||
</div>
|
||||
</template>
|
||||
</section>
|
||||
<section class="draftsContainer" hidden$="[[_computeHideDraftList(_drafts)]]">
|
||||
<h3>[[_computeDraftsTitle(_drafts)]]</h3>
|
||||
<gr-comment-list
|
||||
comments="[[_drafts]]"
|
||||
change-num="[[changeNum]]"
|
||||
patch-num="[[patchNum]]"></gr-comment-list>
|
||||
</section>
|
||||
<section class="actionsContainer">
|
||||
<gr-button primary class="action send" on-tap="_sendTapHandler">Send</gr-button>
|
||||
<gr-button class="action cancel" on-tap="_cancelTapHandler">Cancel</gr-button>
|
||||
</section>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
Polymer({
|
||||
is: 'gr-reply-dropdown',
|
||||
is: 'gr-reply-dialog',
|
||||
|
||||
/**
|
||||
* Fired when a reply is successfully sent.
|
||||
@@ -154,6 +142,12 @@ limitations under the License.
|
||||
* @event send
|
||||
*/
|
||||
|
||||
/**
|
||||
* Fired when the user presses the cancel button.
|
||||
*
|
||||
* @event cancel
|
||||
*/
|
||||
|
||||
properties: {
|
||||
changeNum: String,
|
||||
patchNum: String,
|
||||
@@ -178,29 +172,22 @@ limitations under the License.
|
||||
Gerrit.RESTClientBehavior,
|
||||
],
|
||||
|
||||
get opened() {
|
||||
return this.$.dropdown.opened;
|
||||
},
|
||||
|
||||
ready: function() {
|
||||
app.accountReady.then(function() {
|
||||
this._account = app.account;
|
||||
}.bind(this));
|
||||
},
|
||||
|
||||
open: function() {
|
||||
reload: function() {
|
||||
this.$.draftsXHR.generateRequest();
|
||||
this.$.dropdown.open();
|
||||
},
|
||||
|
||||
focus: function() {
|
||||
this.async(function() {
|
||||
this.$.textarea.textarea.focus();
|
||||
}.bind(this));
|
||||
},
|
||||
|
||||
close: function() {
|
||||
this._drafts = null;
|
||||
this.$.dropdown.close();
|
||||
},
|
||||
|
||||
_computeDraftsURL: function(changeNum) {
|
||||
return '/changes/' + changeNum + '/drafts';
|
||||
},
|
||||
@@ -255,14 +242,10 @@ limitations under the License.
|
||||
return permittedLabels[label];
|
||||
},
|
||||
|
||||
_showPopupTapHandler: function(e) {
|
||||
e.preventDefault();
|
||||
this.open();
|
||||
},
|
||||
|
||||
_cancelTapHandler: function(e) {
|
||||
e.preventDefault();
|
||||
this.$.dropdown.close();
|
||||
this._drafts = null;
|
||||
this.fire('cancel', null, {bubbles: false});
|
||||
},
|
||||
|
||||
_sendTapHandler: function(e) {
|
||||
@@ -285,7 +268,7 @@ limitations under the License.
|
||||
this.fire('send', null, {bubbles: false});
|
||||
this.draft = '';
|
||||
this.disabled = false;
|
||||
this.$.dropdown.close();
|
||||
this._drafts = null;
|
||||
}.bind(this)).catch(function(err) {
|
||||
alert('Oops. Something went wrong. Check the console and bug the ' +
|
||||
'PolyGerrit team for assistance.');
|
||||
Reference in New Issue
Block a user