Add ctrl+enter shortcut for conversations
This commit is contained in:
parent
1fc31cc313
commit
a22127bfb1
7 changed files with 120 additions and 47 deletions
|
|
@ -23,6 +23,7 @@
|
|||
* Hide post title of limited post in comment notification email [#5843](https://github.com/diaspora/diaspora/pull/5843)
|
||||
* More and better environment checks in script/server [#5891](https://github.com/diaspora/diaspora/pull/5891)
|
||||
* Enable aspect sorting again [#5559](https://github.com/diaspora/diaspora/pull/5559)
|
||||
* Submit messages in conversations with Ctrl+Enter [#5910](https://github.com/diaspora/diaspora/pull/5910)
|
||||
|
||||
# 0.5.0.0
|
||||
|
||||
|
|
|
|||
|
|
@ -2,11 +2,15 @@
|
|||
|
||||
app.views.ConversationsForm = Backbone.View.extend({
|
||||
|
||||
events: {
|
||||
"keydown textarea#conversation_text" : "keyDown",
|
||||
},
|
||||
|
||||
initialize: function(opts) {
|
||||
this.contacts = _.has(opts, 'contacts') ? opts.contacts : null;
|
||||
this.contacts = _.has(opts, "contacts") ? opts.contacts : null;
|
||||
this.prefill = [];
|
||||
if (_.has(opts, 'prefillName') && _.has(opts, 'prefillValue')) {
|
||||
this.prefill = [{name : opts.prefillName,
|
||||
if (_.has(opts, "prefillName") && _.has(opts, "prefillValue")) {
|
||||
this.prefill = [{name : opts.prefillName,
|
||||
value : opts.prefillValue}];
|
||||
}
|
||||
this.autocompleteInput = $("#contact_autocomplete");
|
||||
|
|
@ -22,9 +26,15 @@ app.views.ConversationsForm = Backbone.View.extend({
|
|||
minChars: 1,
|
||||
keyDelay: 0,
|
||||
startText: '',
|
||||
emptyText: Diaspora.I18n.t('no_results'),
|
||||
preFill: this.prefill
|
||||
emptyText: Diaspora.I18n.t("no_results"),
|
||||
preFill: this.prefill
|
||||
}).focus();
|
||||
},
|
||||
|
||||
keyDown : function(evt) {
|
||||
if( evt.keyCode === 13 && evt.ctrlKey ) {
|
||||
$(evt.target).parents("form").submit();
|
||||
}
|
||||
}
|
||||
});
|
||||
// @license-end
|
||||
|
|
|
|||
|
|
@ -5,44 +5,54 @@ app.views.Conversations = Backbone.View.extend({
|
|||
el: "#conversations_container",
|
||||
|
||||
events: {
|
||||
"keydown textarea#message_text" : "keyDown",
|
||||
"conversation:loaded" : "setupConversation"
|
||||
},
|
||||
|
||||
initialize: function() {
|
||||
if($('#conversation_new:visible').length > 0) {
|
||||
new app.views.ConversationsForm({contacts: gon.contacts});
|
||||
if($("#conversation_new:visible").length > 0) {
|
||||
new app.views.ConversationsForm({
|
||||
el: $("#conversation_new"),
|
||||
contacts: gon.contacts
|
||||
});
|
||||
}
|
||||
this.setupConversation();
|
||||
},
|
||||
|
||||
setupConversation: function() {
|
||||
app.helpers.timeago($(this.el));
|
||||
$('.control-icons a').tooltip({placement: 'bottom'});
|
||||
$(".control-icons a").tooltip({placement: "bottom"});
|
||||
|
||||
var conv = $('.conversation-wrapper .stream_element.selected'),
|
||||
cBadge = $('#conversations_badge .badge_count');
|
||||
var conv = $(".conversation-wrapper .stream_element.selected"),
|
||||
cBadge = $("#conversations_badge .badge_count");
|
||||
|
||||
if(conv.hasClass('unread') ){
|
||||
var unreadCount = parseInt(conv.find('.unread_message_count').text(), 10);
|
||||
if(conv.hasClass("unread") ){
|
||||
var unreadCount = parseInt(conv.find(".unread_message_count").text(), 10);
|
||||
|
||||
if(cBadge.text() !== '') {
|
||||
if(cBadge.text() !== "") {
|
||||
cBadge.text().replace(/\d+/, function(num){
|
||||
num = parseInt(num, 10) - unreadCount;
|
||||
if(num > 0) {
|
||||
cBadge.text(num);
|
||||
} else {
|
||||
cBadge.text(0).addClass('hidden');
|
||||
cBadge.text(0).addClass("hidden");
|
||||
}
|
||||
});
|
||||
}
|
||||
conv.removeClass('unread');
|
||||
conv.find('.unread_message_count').remove();
|
||||
conv.removeClass("unread");
|
||||
conv.find(".unread_message_count").remove();
|
||||
|
||||
var pos = $('#first_unread').offset().top - 50;
|
||||
var pos = $("#first_unread").offset().top - 50;
|
||||
$("html").animate({scrollTop:pos});
|
||||
} else {
|
||||
$("html").animate({scrollTop:0});
|
||||
}
|
||||
},
|
||||
|
||||
keyDown : function(evt) {
|
||||
if( evt.keyCode === 13 && evt.ctrlKey ) {
|
||||
$(evt.target).parents("form").submit();
|
||||
}
|
||||
}
|
||||
});
|
||||
// @license-end
|
||||
|
|
|
|||
|
|
@ -24,3 +24,15 @@ Feature: private conversations
|
|||
And I should have 1 email delivery
|
||||
When I reply with "hey, how you doing?"
|
||||
Then I should see "hey, how you doing?" within ".stream_container"
|
||||
|
||||
Scenario: send a message using keyboard shortcuts
|
||||
Given I send a message with subject "Greetings" and text "hello, alice!" to "Alice Awesome" using keyboard shortcuts
|
||||
Then I should see "Greetings" within "#conversation_inbox"
|
||||
And I should see "Greetings" within "#conversation_show"
|
||||
And "Alice Awesome" should be part of active conversation
|
||||
And I should see "hello, alice!" within ".stream_container"
|
||||
When I reply with "hey, how you doing?" using keyboard shortcuts
|
||||
Then I should see "hey, how you doing?" within ".stream_container"
|
||||
When I sign in as "alice@alice.alice"
|
||||
Then I should have 2 unread private messages
|
||||
And I should have 2 email delivery
|
||||
|
|
|
|||
|
|
@ -19,6 +19,17 @@ Then /^I send a message with subject "([^"]*)" and text "([^"]*)" to "([^"]*)"$/
|
|||
end
|
||||
end
|
||||
|
||||
Then /^I send a message with subject "([^"]*)" and text "([^"]*)" to "([^"]*)" using keyboard shortcuts$/ do |subject, text, person|
|
||||
step %(I am on the conversations page)
|
||||
within("#conversation_new", match: :first) do
|
||||
step %(I fill in "contact_autocomplete" with "#{person}")
|
||||
step %(I press the first ".as-result-item" within ".as-results")
|
||||
step %(I fill in "conversation_subject" with "#{subject}")
|
||||
step %(I fill in "conversation_text" with "#{text}")
|
||||
find("#conversation_text").native.send_keys :control, :return
|
||||
end
|
||||
end
|
||||
|
||||
When /^I reply with "([^"]*)"$/ do |text|
|
||||
step %(I am on the conversations page)
|
||||
step %(I press the first ".conversation" within ".conversations")
|
||||
|
|
@ -26,6 +37,13 @@ When /^I reply with "([^"]*)"$/ do |text|
|
|||
step %(I press "Reply")
|
||||
end
|
||||
|
||||
When /^I reply with "([^"]*)" using keyboard shortcuts$/ do |text|
|
||||
step %(I am on the conversations page)
|
||||
step %(I press the first ".conversation" within ".conversations")
|
||||
step %(I fill in "message_text" with "#{text}")
|
||||
find("#message_text").native.send_keys :control, :return
|
||||
end
|
||||
|
||||
Then /^I send a mobile message with subject "([^"]*)" and text "([^"]*)" to "([^"]*)"$/ do |subject, text, person|
|
||||
step %(I am on the conversations page)
|
||||
step %(I follow "New conversation")
|
||||
|
|
|
|||
|
|
@ -110,7 +110,7 @@ describe("app.views.CommentStream", function(){
|
|||
form.submit(submitCallback);
|
||||
|
||||
var e = $.Event("keydown", { keyCode: 13 });
|
||||
e.shiftKey = false;
|
||||
e.ctrlKey = false;
|
||||
this.view.keyDownOnCommentBox(e);
|
||||
|
||||
expect(submitCallback).not.toHaveBeenCalled();
|
||||
|
|
|
|||
|
|
@ -1,54 +1,76 @@
|
|||
describe("app.views.Conversations", function(){
|
||||
describe('setupConversation', function() {
|
||||
context('for unread conversations', function() {
|
||||
describe("setupConversation", function() {
|
||||
context("for unread conversations", function() {
|
||||
beforeEach(function() {
|
||||
spec.loadFixture('conversations_unread');
|
||||
spec.loadFixture("conversations_unread");
|
||||
});
|
||||
|
||||
it('removes the unread class from the conversation', function() {
|
||||
expect($('.conversation-wrapper > .conversation.selected')).toHaveClass('unread');
|
||||
it("removes the unread class from the conversation", function() {
|
||||
expect($(".conversation-wrapper > .conversation.selected")).toHaveClass("unread");
|
||||
new app.views.Conversations();
|
||||
expect($('.conversation-wrapper > .conversation.selected')).not.toHaveClass('unread');
|
||||
expect($(".conversation-wrapper > .conversation.selected")).not.toHaveClass("unread");
|
||||
});
|
||||
|
||||
it('removes the unread message counter from the conversation', function() {
|
||||
expect($('.conversation-wrapper > .conversation.selected .unread_message_count').length).toEqual(1);
|
||||
it("removes the unread message counter from the conversation", function() {
|
||||
expect($(".conversation-wrapper > .conversation.selected .unread_message_count").length).toEqual(1);
|
||||
new app.views.Conversations();
|
||||
expect($('.conversation-wrapper > .conversation.selected .unread_message_count').length).toEqual(0);
|
||||
expect($(".conversation-wrapper > .conversation.selected .unread_message_count").length).toEqual(0);
|
||||
});
|
||||
|
||||
it('decreases the unread message count in the header', function() {
|
||||
var badge = '<div id="conversations_badge"><div class="badge_count">3</div></div>';
|
||||
$('header').append(badge);
|
||||
expect($('#conversations_badge .badge_count').text().trim()).toEqual('3');
|
||||
expect($('.conversation-wrapper > .conversation.selected .unread_message_count').text().trim()).toEqual('2');
|
||||
it("decreases the unread message count in the header", function() {
|
||||
var badge = "<div id=\"conversations_badge\"><div class=\"badge_count\">3</div></div>";
|
||||
$("header").append(badge);
|
||||
expect($("#conversations_badge .badge_count").text().trim()).toEqual("3");
|
||||
expect($(".conversation-wrapper > .conversation.selected .unread_message_count").text().trim()).toEqual("2");
|
||||
new app.views.Conversations();
|
||||
expect($('#conversations_badge .badge_count').text().trim()).toEqual('1');
|
||||
expect($("#conversations_badge .badge_count").text().trim()).toEqual("1");
|
||||
});
|
||||
|
||||
it('removes the badge_count in the header if there are no unread messages left', function() {
|
||||
var badge = '<div id="conversations_badge"><div class="badge_count">2</div></div>';
|
||||
$('header').append(badge);
|
||||
expect($('#conversations_badge .badge_count').text().trim()).toEqual('2');
|
||||
expect($('.conversation-wrapper > .conversation.selected .unread_message_count').text().trim()).toEqual('2');
|
||||
it("removes the badge_count in the header if there are no unread messages left", function() {
|
||||
var badge = "<div id=\"conversations_badge\"><div class=\"badge_count\">2</div></div>";
|
||||
$("header").append(badge);
|
||||
expect($("#conversations_badge .badge_count").text().trim()).toEqual("2");
|
||||
expect($(".conversation-wrapper > .conversation.selected .unread_message_count").text().trim()).toEqual("2");
|
||||
new app.views.Conversations();
|
||||
expect($('#conversations_badge .badge_count').text().trim()).toEqual('0');
|
||||
expect($('#conversations_badge .badge_count')).toHaveClass('hidden');
|
||||
expect($("#conversations_badge .badge_count").text().trim()).toEqual("0");
|
||||
expect($("#conversations_badge .badge_count")).toHaveClass("hidden");
|
||||
});
|
||||
});
|
||||
|
||||
context('for read conversations', function() {
|
||||
context("for read conversations", function() {
|
||||
beforeEach(function() {
|
||||
spec.loadFixture('conversations_read');
|
||||
spec.loadFixture("conversations_read");
|
||||
});
|
||||
|
||||
it('does not change the badge_count in the header', function() {
|
||||
var badge = '<div id="conversations_badge"><div class="badge_count">3</div></div>';
|
||||
$('header').append(badge);
|
||||
expect($('#conversations_badge .badge_count').text().trim()).toEqual('3');
|
||||
it("does not change the badge_count in the header", function() {
|
||||
var badge = "<div id=\"conversations_badge\"><div class=\"badge_count\">3</div></div>";
|
||||
$("header").append(badge);
|
||||
expect($("#conversations_badge .badge_count").text().trim()).toEqual("3");
|
||||
new app.views.Conversations();
|
||||
expect($('#conversations_badge .badge_count').text().trim()).toEqual('3');
|
||||
expect($("#conversations_badge .badge_count").text().trim()).toEqual("3");
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("keyDown", function(){
|
||||
beforeEach(function() {
|
||||
this.submitCallback = jasmine.createSpy().and.returnValue(false);
|
||||
spec.loadFixture("conversations_read");
|
||||
new app.views.Conversations();
|
||||
});
|
||||
|
||||
it("should submit the form with ctrl+enter", function(){
|
||||
$("form#new_message").submit(this.submitCallback);
|
||||
var e = $.Event("keydown", { keyCode: 13, ctrlKey: true });
|
||||
$("textarea#message_text").trigger(e);
|
||||
expect(this.submitCallback).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("shouldn't submit the form without the ctrl key", function(){
|
||||
$("form#new_message").submit(this.submitCallback);
|
||||
var e = $.Event("keydown", { keyCode: 13, ctrlKey: false });
|
||||
$("textarea#message_text").trigger(e);
|
||||
expect(this.submitCallback).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in a new issue