From 9384870ffa955ee4f800738d0cee1cf18b10d682 Mon Sep 17 00:00:00 2001 From: Waseem Daher Date: Fri, 3 May 2013 16:16:52 -0400 Subject: [PATCH] Always-open composebox. Really, the "correct" way to do this is to undo "scrolltheworld", and then just have a compose div that always lives underneath the message list div. (This will also allow us to deal much more reasonably with the whole "Is the composebox in focus" thing.) In the interest of prototyping something more rapidly, though, we adopt the somewhat more hackish approach, with the understanding that much of it will probably be simplified later. (imported from commit e2754be155c522b6dac28e7b84c62bd2030217c8) --- templates/zephyr/compose.html | 1 - zephyr/static/js/compose.js | 21 +++++++++++++++------ zephyr/static/js/message_list.js | 2 +- zephyr/static/js/notifications_bar.js | 2 +- zephyr/static/js/ui.js | 23 +++++++++++++++++++++++ zephyr/static/styles/zephyr.css | 13 ++----------- zephyr/tests/frontend/common.js | 2 +- zephyr/tests/frontend/tests/03-compose.js | 14 +++++++------- 8 files changed, 50 insertions(+), 28 deletions(-) diff --git a/templates/zephyr/compose.html b/templates/zephyr/compose.html index 0dc1ef6870..53859b44ac 100644 --- a/templates/zephyr/compose.html +++ b/templates/zephyr/compose.html @@ -1,6 +1,5 @@
-
×
× diff --git a/zephyr/static/js/compose.js b/zephyr/static/js/compose.js index 0282c17981..9d849fca7e 100644 --- a/zephyr/static/js/compose.js +++ b/zephyr/static/js/compose.js @@ -213,10 +213,6 @@ exports.start = function (msg_type, opts) { show('private', $("#" + (focus_area || 'private_message_recipient'))); } - if (message_snapshot !== undefined) { - $('#restore-draft').show(); - } - if (opts.replying_to_message !== undefined) { do_fade(opts.replying_to_message, msg_type); } @@ -239,6 +235,10 @@ exports.cancel = function () { compose.hide(); abort_xhr(); is_composing_message = false; + compose.clear(); + if (message_snapshot !== undefined) { + $('#restore-draft').show(); + } $(document).trigger($.Event('compose_canceled.zephyr')); }; @@ -383,8 +383,8 @@ $(function () { exports.hide = function () { exports.snapshot_message(); $('.message_comp').find('input, textarea, button').blur(); - $('.message_comp').slideUp(100, - function() { $('#compose').css({visibility: "hidden"});}); + $('#stream-message').hide(); + $('#private-message').hide(); notifications_bar.enable(); exports.unfade_messages(true); }; @@ -540,6 +540,15 @@ exports.validate = function () { $(function () { $("#new_message_content").autosize(); + + $("#new_message_content").click(function (e) { + // If we click in the composebox, start up a new message + if (!compose.composing()) { + respond_to_message(); + e.stopPropagation(); + } + }); + $("#compose").filedrop({ url: "json/upload_file", fallback_id: "file_input", diff --git a/zephyr/static/js/message_list.js b/zephyr/static/js/message_list.js index 1bb6947dfe..9bbc6f0cff 100644 --- a/zephyr/static/js/message_list.js +++ b/zephyr/static/js/message_list.js @@ -433,7 +433,7 @@ MessageList.prototype = { var selected_row_offset = selected_row.offset().top; var available_space_for_scroll = selected_row_offset - viewport_offset - - $("#floating_recipient_bar").height() - $("#searchbox_form").height(); + $("#floating_recipient_bar").height() - $("#searchbox_form").height() - $("#compose").height(); suppress_scroll_pointer_update = true; // Gets set to false in the scroll handler. // viewport (which is window) doesn't have a scrollTop, so scroll diff --git a/zephyr/static/js/notifications_bar.js b/zephyr/static/js/notifications_bar.js index fce73b116f..8cb9598543 100644 --- a/zephyr/static/js/notifications_bar.js +++ b/zephyr/static/js/notifications_bar.js @@ -53,7 +53,7 @@ exports.update = function () { if (on_custom) show(custom_message); else if (rows.last_visible().offset() !== null // otherwise the next line will error - && rows.last_visible().offset().top + rows.last_visible().height() > viewport.scrollTop() + viewport.height() + && rows.last_visible().offset().top + rows.last_visible().height() > viewport.scrollTop() + viewport.height() - $("#compose").height() && unread_in_current_view() > 0) show("More messages below"); else diff --git a/zephyr/static/js/ui.js b/zephyr/static/js/ui.js index 34ad8478d2..07fa01dc0c 100644 --- a/zephyr/static/js/ui.js +++ b/zephyr/static/js/ui.js @@ -866,6 +866,7 @@ $(function () { var row = $(this).closest(".message_row"); current_msg_list.select_id(rows.id(row)); respond_to_message(); + e.stopPropagation(); } mouse_moved = false; clicking = false; @@ -1018,7 +1019,16 @@ $(function () { $('#user_presences').on('click', 'a', function (e) { var email = $(e.target).attr('data-email'); compose.start('private', {private_message_recipient: email}); + // The preventDefault is necessary so that clicking the + // link doesn't jump us to the top of the page. e.preventDefault(); + // The stopPropagation is necessary so that we don't + // see the following sequence of events: + // 1. This click "opens" the composebox + // 2. This event propagates to the body, which says "oh, hey, the + // composebox is open and you clicked out of it, you must want to + // stop composing!" + e.stopPropagation(); }); $('#stream_filters li').on('click', 'a.subscription_name', function (e) { @@ -1126,6 +1136,19 @@ $(function () { if ($('.popover-inner').has(e.target).length === 0) { ui.hide_actions_popover(); } + + // Unfocus our compose area if we click out of it. + if (compose.composing()) { + compose.cancel(); + } + }); + + $("#compose").click(function (e) { + // Don't let clicks in the compose area count as + // "unfocusing" our compose -- in other words, e.g. + // clicking "Press enter to send" should not + // trigger the composebox-closing code above. + e.stopPropagation(); }); // side-bar-related handlers diff --git a/zephyr/static/styles/zephyr.css b/zephyr/static/styles/zephyr.css index 3e7e221ce6..191e6a5bcb 100644 --- a/zephyr/static/styles/zephyr.css +++ b/zephyr/static/styles/zephyr.css @@ -265,7 +265,6 @@ ul.filters i { } .message_comp { - display: none; border: 1px solid #EEE; background-color: white; padding: 8px 20px 8px 10px; @@ -503,6 +502,7 @@ blockquote p { /* normally 5px 14px; pull in the right and bottom a bit */ padding-right: 5px; padding-bottom: 0px; + border-top-width: 1px; cursor: default; } @@ -559,7 +559,6 @@ img.inline_profile_picture { } #compose { - visibility: hidden; position: fixed; bottom: 0px; background: white; @@ -584,21 +583,12 @@ img.inline_profile_picture { float: right; } -.composebox-close { - padding: 5px; - padding-top: 8px; /* = message_comp padding_top */ -} - .send-status-close:hover { cursor: pointer; opacity: .4; filter: alpha(opacity=40); } -.compose_table #private-message { - display: none; -} - .home-error-bar { margin-top: 5px; display: none; @@ -1072,6 +1062,7 @@ table.floating_recipient { #stream-message, #private-message { border: 1px solid grey; + display: none; } .emoji { diff --git a/zephyr/tests/frontend/common.js b/zephyr/tests/frontend/common.js index 92840364cf..653369f99b 100644 --- a/zephyr/tests/frontend/common.js +++ b/zephyr/tests/frontend/common.js @@ -93,7 +93,7 @@ exports.send_message = function (type, params) { casper.click('#left_bar_compose_' + type + '_button_big'); casper.fill('form[action^="/json/send_message"]', params); casper.click('#compose-send-button'); - casper.waitWhileVisible('#compose', function () { + casper.waitWhileVisible('#stream,#private-message', function () { last_send_or_update = timestamp(); }); }); diff --git a/zephyr/tests/frontend/tests/03-compose.js b/zephyr/tests/frontend/tests/03-compose.js index 83bc09f1fd..6c2f633ebc 100644 --- a/zephyr/tests/frontend/tests/03-compose.js +++ b/zephyr/tests/frontend/tests/03-compose.js @@ -13,20 +13,20 @@ casper.then(function () { casper.click('#left_bar_compose_stream_button_big'); casper.test.assertVisible('#stream', 'Switching from PM compose to stream compose'); - // Test closing the compose box - casper.click('.composebox-close'); + // Test "closing" the compose box + casper.click('body'); }); -casper.waitWhileVisible('#compose'); +casper.waitWhileVisible('#stream'); casper.then(function () { - casper.test.assertNotVisible('#compose', 'Close stream compose box'); + casper.test.assertNotVisible('#stream', 'Close stream compose box'); casper.click('#left_bar_compose_private_button_big'); - casper.click('.composebox-close'); + casper.click('body'); }); -casper.waitWhileVisible('#compose'); +casper.waitWhileVisible('#private-message'); casper.then(function () { - casper.test.assertNotVisible('#compose', 'Close PM compose box'); + casper.test.assertNotVisible('#private-message', 'Close PM compose box'); }); common.then_log_out();