mozreview: make double-clicking to open a comment optional per user (
bug 1246769); r?mdoglio
MozReview-Commit-ID: 9cZ83ZehALQ
--- a/pylib/mozreview/mozreview/extension.py
+++ b/pylib/mozreview/mozreview/extension.py
@@ -2,17 +2,18 @@ from __future__ import unicode_literals
import json
import logging
import os
from django.conf.urls import include, patterns, url
from reviewboard.extensions.base import Extension, JSExtension
-from reviewboard.extensions.hooks import (HeaderDropdownActionHook,
+from reviewboard.extensions.hooks import (AccountPagesHook,
+ HeaderDropdownActionHook,
HostingServiceHook,
ReviewRequestDropdownActionHook,
ReviewRequestFieldsHook,
TemplateHook,
URLHook)
from reviewboard.reviews.builtin_fields import (TestingDoneField,
BranchField,
DependsOnField,
@@ -58,16 +59,17 @@ from mozreview.hostingservice.hmo_reposi
)
from mozreview.ldap.resources import (
ldap_association_resource,
)
from mozreview.middleware import (
MozReviewCacheDisableMiddleware,
MozReviewUserProfileMiddleware,
)
+
from mozreview.pulse import (
initialize_pulse_handlers,
)
from mozreview.resources.bugzilla_login import (
bugzilla_api_key_login_resource,
)
from mozreview.resources.batch_review_request import (
batch_review_request_resource,
@@ -292,16 +294,21 @@ class MozReviewExtension(Extension):
initialize_signal_handlers(self)
HostingServiceHook(self, HMORepository)
URLHook(self, patterns('',
url(r'^import-pullrequest/(?P<user>.+)/(?P<repo>.+)/(?P<pullrequest>\d+)/$',
import_pullrequest, name='import_pullrequest')))
+ # Importing here to avoid an import loop
+ from mozreview.pages import MozReviewAccountSettingsPage
+
+ AccountPagesHook(self, [MozReviewAccountSettingsPage])
+
def shutdown(self):
# We have to put the TestingDone field back before we shut down
# in order to get the instance back to its original state.
main_fieldset = get_review_request_fieldset('main')
if not get_review_request_field('testing_done'):
main_fieldset.add_field(TestingDoneField)
info_fieldset = get_review_request_fieldset('info')
--- a/pylib/mozreview/mozreview/forms.py
+++ b/pylib/mozreview/mozreview/forms.py
@@ -1,13 +1,48 @@
from django import forms
+from django.contrib import messages
from django.utils.translation import ugettext as _
from djblets.extensions.forms import SettingsForm
+from reviewboard.accounts.forms.pages import AccountPageForm
+
import mozreview.extension
class MozReviewSettingsForm(SettingsForm):
config = forms.CharField(
required=False,
help_text=_('Configure this extension by editing ' +
mozreview.extension.SETTINGS_PATH)
)
+
+
+class MozReviewAccountSettingsForm(AccountPageForm):
+ form_id = 'mozreview_accountsettings_page'
+ extra_data_key = 'mozreview_dblclick_comment'
+ form_title = 'Additional MozReview Customizations'
+ default = True
+
+ mozreview_dblclick_comment = forms.BooleanField(
+ label=_('Double-clicking a line number should start a comment'),
+ help_text=_('This is similar to how Bugzilla Splinter behaves'),
+ initial=True,
+ required=False)
+
+ def load(self):
+ """Loads in data for the Account Settings form"""
+ current = self.default
+ if self.extra_data_key in self.profile.extra_data:
+ current = self.profile.extra_data[self.extra_data_key]
+
+ self.set_initial({
+ self.extra_data_key: current,
+ })
+
+ def save(self):
+ """Save data for the Account Settings form"""
+ cleaned = self.cleaned_data[self.extra_data_key]
+ self.profile.extra_data[self.extra_data_key] = cleaned
+ self.profile.save(update_fields=('extra_data',))
+
+ messages.add_message(self.request, messages.INFO,
+ _('Your settings have been saved.'))
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/pylib/mozreview/mozreview/pages.py
@@ -0,0 +1,10 @@
+from __future__ import unicode_literals
+
+from mozreview.forms import MozReviewAccountSettingsForm
+from reviewboard.accounts.pages import AccountPage
+
+
+class MozReviewAccountSettingsPage(AccountPage):
+ page_id = 'mozreview_accountsettings_page'
+ page_title = 'MozReview Customizations'
+ form_classes = [MozReviewAccountSettingsForm]
--- a/pylib/mozreview/mozreview/static/mozreview/js/diffviewer_customizations.js
+++ b/pylib/mozreview/mozreview/static/mozreview/js/diffviewer_customizations.js
@@ -2,16 +2,21 @@
* Monkey-patch RB.TextCommentRowSelector so that double-clicks will
* result in a comment being opened, a la Splinter.
*/
RB.TextCommentRowSelector = RB.TextCommentRowSelector.extend({
events: _.extend({
'dblclick': '_onDoubleClick',
}, RB.TextCommentRowSelector.prototype.events),
+ initialize: function() {
+ _super(this).initialize.apply(this, arguments);
+ this._isEnabled = $('#mozreview-dblclick-comment').data('value');
+ },
+
/*
* Returns whether a node represents source code in the diff viewer.
*
* A node represents source code when it is within the section of
* the diff viewer that's actually displaying code. That means
* that it's within a <td> with a class "l", or a <td> with class
* "r".
*/
@@ -29,16 +34,20 @@ RB.TextCommentRowSelector = RB.TextComme
/*
* Handler for when the user double-clicks on a row.
*
* This will open a comment dialog for the row that the user
* double-clicked on.
*/
_onDoubleClick: function(e) {
+ if (!this._isEnabled) {
+ return;
+ }
+
var node = e.target,
$row,
lineNum;
if (this._isWithinCodeCell(node)) {
$row = this._getRowFromChild($(node));
lineNum = this.getLineNum($row[0]);
this.options.reviewableView.createAndEditCommentBlock({
--- a/pylib/mozreview/mozreview/templates/mozreview/review-scripts-js.html
+++ b/pylib/mozreview/mozreview/templates/mozreview/review-scripts-js.html
@@ -3,10 +3,16 @@
{% if review_request|isPush %}
{% ext_js_bundle extension "reviews" %}
{% if review_request|isSquashed %}
{% ext_js_bundle extension "try" %}
{% endif %}
+{% comment %}
+TODO: This should get moved into the "diffviewer only" TemplateHook once
+bug 1248364 is closed.
+{% endcomment %}
+<div id="mozreview-dblclick-comment" data-value="{{ user_profile|dblclick_comment|yesno:'true,false' }}"></div>
+
{% endif %}
--- a/pylib/mozreview/mozreview/templatetags/mozreview.py
+++ b/pylib/mozreview/mozreview/templatetags/mozreview.py
@@ -32,18 +32,21 @@ def commit_id(review_request_details):
def reviewer_list(review_request):
return ', '.join([user.username
for user in review_request.target_people.all()])
@register.filter()
-def extra_data(review_request, key):
- return review_request.extra_data[key]
+def dblclick_comment(user_profile):
+ try:
+ return user_profile.extra_data['mozreview_dblclick_comment']
+ except (AttributeError, KeyError):
+ return 'true'
@register.filter()
def scm_level(mozreview_profile):
if mozreview_profile is None:
return ''
elif mozreview_profile.has_scm_ldap_group('scm_level_3'):
return '3'