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)
This commit is contained in:
Waseem Daher
2013-05-03 16:16:52 -04:00
committed by Tim Abbott
parent 96100bb42a
commit 9384870ffa
8 changed files with 50 additions and 28 deletions

View File

@@ -1,6 +1,5 @@
<div class="row-fluid"> <div class="row-fluid">
<div class="span12" id="compose"> <div class="span12" id="compose">
<div class="close composebox-close">&times;</div>
<div class="message_comp"> <div class="message_comp">
<div class="alert" id="send-status"> <div class="alert" id="send-status">
<span class="send-status-close">&times;</span> <span class="send-status-close">&times;</span>

View File

@@ -213,10 +213,6 @@ exports.start = function (msg_type, opts) {
show('private', $("#" + (focus_area || 'private_message_recipient'))); show('private', $("#" + (focus_area || 'private_message_recipient')));
} }
if (message_snapshot !== undefined) {
$('#restore-draft').show();
}
if (opts.replying_to_message !== undefined) { if (opts.replying_to_message !== undefined) {
do_fade(opts.replying_to_message, msg_type); do_fade(opts.replying_to_message, msg_type);
} }
@@ -239,6 +235,10 @@ exports.cancel = function () {
compose.hide(); compose.hide();
abort_xhr(); abort_xhr();
is_composing_message = false; is_composing_message = false;
compose.clear();
if (message_snapshot !== undefined) {
$('#restore-draft').show();
}
$(document).trigger($.Event('compose_canceled.zephyr')); $(document).trigger($.Event('compose_canceled.zephyr'));
}; };
@@ -383,8 +383,8 @@ $(function () {
exports.hide = function () { exports.hide = function () {
exports.snapshot_message(); exports.snapshot_message();
$('.message_comp').find('input, textarea, button').blur(); $('.message_comp').find('input, textarea, button').blur();
$('.message_comp').slideUp(100, $('#stream-message').hide();
function() { $('#compose').css({visibility: "hidden"});}); $('#private-message').hide();
notifications_bar.enable(); notifications_bar.enable();
exports.unfade_messages(true); exports.unfade_messages(true);
}; };
@@ -540,6 +540,15 @@ exports.validate = function () {
$(function () { $(function () {
$("#new_message_content").autosize(); $("#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({ $("#compose").filedrop({
url: "json/upload_file", url: "json/upload_file",
fallback_id: "file_input", fallback_id: "file_input",

View File

@@ -433,7 +433,7 @@ MessageList.prototype = {
var selected_row_offset = selected_row.offset().top; var selected_row_offset = selected_row.offset().top;
var available_space_for_scroll = selected_row_offset - viewport_offset - 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. suppress_scroll_pointer_update = true; // Gets set to false in the scroll handler.
// viewport (which is window) doesn't have a scrollTop, so scroll // viewport (which is window) doesn't have a scrollTop, so scroll

View File

@@ -53,7 +53,7 @@ exports.update = function () {
if (on_custom) if (on_custom)
show(custom_message); show(custom_message);
else if (rows.last_visible().offset() !== null // otherwise the next line will error 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) && unread_in_current_view() > 0)
show("More messages below"); show("More messages below");
else else

View File

@@ -866,6 +866,7 @@ $(function () {
var row = $(this).closest(".message_row"); var row = $(this).closest(".message_row");
current_msg_list.select_id(rows.id(row)); current_msg_list.select_id(rows.id(row));
respond_to_message(); respond_to_message();
e.stopPropagation();
} }
mouse_moved = false; mouse_moved = false;
clicking = false; clicking = false;
@@ -1018,7 +1019,16 @@ $(function () {
$('#user_presences').on('click', 'a', function (e) { $('#user_presences').on('click', 'a', function (e) {
var email = $(e.target).attr('data-email'); var email = $(e.target).attr('data-email');
compose.start('private', {private_message_recipient: 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(); 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) { $('#stream_filters li').on('click', 'a.subscription_name', function (e) {
@@ -1126,6 +1136,19 @@ $(function () {
if ($('.popover-inner').has(e.target).length === 0) { if ($('.popover-inner').has(e.target).length === 0) {
ui.hide_actions_popover(); 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 // side-bar-related handlers

View File

@@ -265,7 +265,6 @@ ul.filters i {
} }
.message_comp { .message_comp {
display: none;
border: 1px solid #EEE; border: 1px solid #EEE;
background-color: white; background-color: white;
padding: 8px 20px 8px 10px; padding: 8px 20px 8px 10px;
@@ -503,6 +502,7 @@ blockquote p {
/* normally 5px 14px; pull in the right and bottom a bit */ /* normally 5px 14px; pull in the right and bottom a bit */
padding-right: 5px; padding-right: 5px;
padding-bottom: 0px; padding-bottom: 0px;
border-top-width: 1px;
cursor: default; cursor: default;
} }
@@ -559,7 +559,6 @@ img.inline_profile_picture {
} }
#compose { #compose {
visibility: hidden;
position: fixed; position: fixed;
bottom: 0px; bottom: 0px;
background: white; background: white;
@@ -584,21 +583,12 @@ img.inline_profile_picture {
float: right; float: right;
} }
.composebox-close {
padding: 5px;
padding-top: 8px; /* = message_comp padding_top */
}
.send-status-close:hover { .send-status-close:hover {
cursor: pointer; cursor: pointer;
opacity: .4; opacity: .4;
filter: alpha(opacity=40); filter: alpha(opacity=40);
} }
.compose_table #private-message {
display: none;
}
.home-error-bar { .home-error-bar {
margin-top: 5px; margin-top: 5px;
display: none; display: none;
@@ -1072,6 +1062,7 @@ table.floating_recipient {
#stream-message, #private-message { #stream-message, #private-message {
border: 1px solid grey; border: 1px solid grey;
display: none;
} }
.emoji { .emoji {

View File

@@ -93,7 +93,7 @@ exports.send_message = function (type, params) {
casper.click('#left_bar_compose_' + type + '_button_big'); casper.click('#left_bar_compose_' + type + '_button_big');
casper.fill('form[action^="/json/send_message"]', params); casper.fill('form[action^="/json/send_message"]', params);
casper.click('#compose-send-button'); casper.click('#compose-send-button');
casper.waitWhileVisible('#compose', function () { casper.waitWhileVisible('#stream,#private-message', function () {
last_send_or_update = timestamp(); last_send_or_update = timestamp();
}); });
}); });

View File

@@ -13,20 +13,20 @@ casper.then(function () {
casper.click('#left_bar_compose_stream_button_big'); casper.click('#left_bar_compose_stream_button_big');
casper.test.assertVisible('#stream', 'Switching from PM compose to stream compose'); casper.test.assertVisible('#stream', 'Switching from PM compose to stream compose');
// Test closing the compose box // Test "closing" the compose box
casper.click('.composebox-close'); casper.click('body');
}); });
casper.waitWhileVisible('#compose'); casper.waitWhileVisible('#stream');
casper.then(function () { 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('#left_bar_compose_private_button_big');
casper.click('.composebox-close'); casper.click('body');
}); });
casper.waitWhileVisible('#compose'); casper.waitWhileVisible('#private-message');
casper.then(function () { casper.then(function () {
casper.test.assertNotVisible('#compose', 'Close PM compose box'); casper.test.assertNotVisible('#private-message', 'Close PM compose box');
}); });
common.then_log_out(); common.then_log_out();