mirror of
https://github.com/zulip/zulip.git
synced 2025-11-13 18:36:36 +00:00
Revised message actions and message info popovers
Since f8fbf70c8502 had troubles in FF and people did not like the message-info-on-hover, this commit hopefully will work better. Tables are likely the culprit with using dropdowns in FF, so when we stop having the messagelist be at table, we can switch back to dropdowns which are relatively positioned rather than absolutely on the page. (imported from commit c49a5cd45f3439d089146771e2aa0cee6431125a)
This commit is contained in:
@@ -103,6 +103,10 @@
|
||||
<td class="hotkey">?</td>
|
||||
<td class="definition">Open keyboard shortcut help</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="hotkey">i</td>
|
||||
<td class="definition">Open message actions menu</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
|
||||
@@ -18,6 +18,14 @@ var directional_hotkeys = {
|
||||
'home': {getrow: rows.first_visible, direction: -1, charCode: 0} // Home
|
||||
};
|
||||
|
||||
var actions_dropdown_hotkeys = [
|
||||
'down_arrow',
|
||||
'up_arrow',
|
||||
'vim_up',
|
||||
'vim_down',
|
||||
'enter'
|
||||
];
|
||||
|
||||
function get_event_name(e) {
|
||||
if ((e.which === 9) && e.shiftKey) {
|
||||
return 'shift_tab';
|
||||
@@ -72,6 +80,8 @@ function get_event_name(e) {
|
||||
return 'narrow_by_subject';
|
||||
case 99: // 'c'
|
||||
return 'compose';
|
||||
case 105: // 'i'
|
||||
return 'message_actions';
|
||||
case 106: // 'j'
|
||||
return 'vim_down';
|
||||
case 107: // 'k'
|
||||
@@ -103,6 +113,11 @@ function process_hotkey(e) {
|
||||
|
||||
var next_row, dirkey;
|
||||
|
||||
if (popovers.actions_popped() && actions_dropdown_hotkeys.indexOf(event_name) !== -1) {
|
||||
popovers.actions_menu_handle_keyboard(event_name);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Handle a few keys specially when the send button is focused.
|
||||
if ($('#compose-send-button').is(':focus')) {
|
||||
if (event_name === 'backspace') {
|
||||
@@ -207,6 +222,10 @@ function process_hotkey(e) {
|
||||
}
|
||||
|
||||
switch (event_name) {
|
||||
case 'message_actions':
|
||||
var id = current_msg_list.selected_id();
|
||||
popovers.show_actions_popover($(".selected_message .actions_hover")[0], id);
|
||||
return true;
|
||||
case 'narrow_by_recipient':
|
||||
return do_narrow_action(narrow.by_recipient);
|
||||
case 'narrow_by_subject':
|
||||
|
||||
@@ -3,9 +3,10 @@ var popovers = (function () {
|
||||
var exports = {};
|
||||
|
||||
var current_actions_popover_elem;
|
||||
var current_message_info_popover_elem;
|
||||
|
||||
function show_actions_popover(element, id) {
|
||||
var last_popover_elem = current_actions_popover_elem;
|
||||
function show_message_info_popover(element, id) {
|
||||
var last_popover_elem = current_message_info_popover_elem;
|
||||
popovers.hide_all();
|
||||
if (last_popover_elem !== undefined
|
||||
&& last_popover_elem.get()[0] === element) {
|
||||
@@ -13,7 +14,6 @@ function show_actions_popover(element, id) {
|
||||
// by clicking on the same element that caused the popover.
|
||||
return;
|
||||
}
|
||||
|
||||
current_msg_list.select_id(id);
|
||||
var elt = $(element);
|
||||
if (elt.data('popover') === undefined) {
|
||||
@@ -31,26 +31,91 @@ function show_actions_popover(element, id) {
|
||||
var ypos = elt.offset().top - viewport.scrollTop();
|
||||
elt.popover({
|
||||
placement: (ypos > (viewport.height() - 300)) ? 'top' : 'bottom',
|
||||
title: templates.render('actions_popover_title', args),
|
||||
title: templates.render('message_info_popover_title', args),
|
||||
content: templates.render('message_info_popover_content', args),
|
||||
trigger: "manual"
|
||||
});
|
||||
elt.popover("show");
|
||||
current_message_info_popover_elem = elt;
|
||||
}
|
||||
}
|
||||
|
||||
exports.show_actions_popover = function (element, id) {
|
||||
var last_popover_elem = current_actions_popover_elem;
|
||||
popovers.hide_all();
|
||||
if (last_popover_elem !== undefined
|
||||
&& last_popover_elem.get()[0] === element) {
|
||||
// We want it to be the case that a user can dismiss a popover
|
||||
// by clicking on the same element that caused the popover.
|
||||
return;
|
||||
}
|
||||
|
||||
current_msg_list.select_id(id);
|
||||
var elt = $(element);
|
||||
if (elt.data('popover') === undefined) {
|
||||
var message = current_msg_list.get(id);
|
||||
var can_edit = message.sent_by_me;
|
||||
var args = {
|
||||
message: message,
|
||||
can_edit_message: can_edit,
|
||||
narrowed: narrow.active()
|
||||
};
|
||||
|
||||
var ypos = elt.offset().top - viewport.scrollTop();
|
||||
elt.popover({
|
||||
placement: (ypos > (viewport.height() - 300)) ? 'top' : 'bottom',
|
||||
title: "",
|
||||
content: templates.render('actions_popover_content', args),
|
||||
trigger: "manual"
|
||||
});
|
||||
elt.popover("show");
|
||||
current_actions_popover_elem = elt;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
function actions_popped() {
|
||||
return current_actions_popover_elem !== undefined;
|
||||
exports.actions_menu_handle_keyboard = function (key) {
|
||||
var items = $('li:not(.divider):visible a', current_actions_popover_elem.data('popover').$tip);
|
||||
var index = items.index(items.filter(':focus'));
|
||||
|
||||
if (key === "enter" && index >= 0 && index < items.length) {
|
||||
return items.eq(index).trigger('click');
|
||||
}
|
||||
if (index === -1) {
|
||||
index = 0;
|
||||
}
|
||||
else if ((key === 'down_arrow' || key === 'vim_down') && index < items.length - 1) {
|
||||
++index;
|
||||
}
|
||||
else if ((key === 'up_arrow' || key === 'vim_up') && index > 0) {
|
||||
--index;
|
||||
}
|
||||
items.eq(index).focus();
|
||||
};
|
||||
|
||||
exports.actions_popped = function () {
|
||||
return current_actions_popover_elem !== undefined;
|
||||
};
|
||||
|
||||
exports.hide_actions_popover = function () {
|
||||
if (actions_popped()) {
|
||||
if (popovers.actions_popped()) {
|
||||
current_actions_popover_elem.popover("destroy");
|
||||
current_actions_popover_elem = undefined;
|
||||
}
|
||||
};
|
||||
|
||||
function message_info_popped() {
|
||||
return current_message_info_popover_elem !== undefined;
|
||||
}
|
||||
|
||||
exports.hide_message_info_popover = function () {
|
||||
if (message_info_popped()) {
|
||||
current_message_info_popover_elem.popover("destroy");
|
||||
current_message_info_popover_elem = undefined;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
var current_stream_sidebar_elem;
|
||||
var current_user_sidebar_elem;
|
||||
|
||||
@@ -84,9 +149,16 @@ exports.register_click_handlers = function () {
|
||||
$("#main_div").on("click", ".actions_hover", function (e) {
|
||||
var row = $(this).closest(".message_row");
|
||||
e.stopPropagation();
|
||||
show_actions_popover(this, rows.id(row));
|
||||
popovers.show_actions_popover(this, rows.id(row));
|
||||
});
|
||||
|
||||
$("#main_div").on("click", ".sender_info_hover", function (e) {
|
||||
var row = $(this).closest(".message_row");
|
||||
e.stopPropagation();
|
||||
show_message_info_popover(this, rows.id(row));
|
||||
});
|
||||
|
||||
|
||||
$('body').on('click', '.user_sidebar_entry', function (e) {
|
||||
var last_sidebar_elem = current_user_sidebar_elem;
|
||||
popovers.hide_all();
|
||||
@@ -198,29 +270,34 @@ exports.register_click_handlers = function () {
|
||||
respond_to_message({trigger: 'popover respond'});
|
||||
popovers.hide_actions_popover();
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
});
|
||||
$('body').on('click', '.respond_personal_button', function (e) {
|
||||
respond_to_message({reply_type: 'personal', trigger: 'popover respond pm'});
|
||||
popovers.hide_actions_popover();
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
});
|
||||
$('body').on('click', '.popover_narrow_by_subject_button', function (e) {
|
||||
var msgid = $(e.currentTarget).data('msgid');
|
||||
popovers.hide_actions_popover();
|
||||
narrow.by_subject(msgid, {trigger: 'popover'});
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
});
|
||||
$('body').on('click', '.popover_narrow_by_recipient_button', function (e) {
|
||||
var msgid = $(e.currentTarget).data('msgid');
|
||||
popovers.hide_actions_popover();
|
||||
narrow.by_recipient(msgid, {trigger: 'popover'});
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
});
|
||||
$('body').on('click', '.popover_narrow_by_time_travel_button', function (e) {
|
||||
var msgid = $(e.currentTarget).data('msgid');
|
||||
popovers.hide_actions_popover();
|
||||
narrow.by_time_travel(msgid, {trigger: 'popover'});
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
});
|
||||
$('body').on('click', '.popover_toggle_collapse', function (e) {
|
||||
var msgid = $(e.currentTarget).data('msgid');
|
||||
@@ -236,6 +313,7 @@ exports.register_click_handlers = function () {
|
||||
}
|
||||
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
});
|
||||
$('body').on('click', '.popover_edit_message', function (e) {
|
||||
var msgid = $(e.currentTarget).data('msgid');
|
||||
@@ -243,6 +321,7 @@ exports.register_click_handlers = function () {
|
||||
popovers.hide_actions_popover();
|
||||
message_edit.start(row);
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
});
|
||||
|
||||
$('body').on('click', '.toggle_home', function (e) {
|
||||
@@ -281,15 +360,17 @@ exports.register_click_handlers = function () {
|
||||
subs.show_settings_for(stream);
|
||||
}
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
exports.any_active = function () {
|
||||
// True if any popover (that this module manages) is currently shown.
|
||||
return actions_popped() || user_sidebar_popped() || stream_sidebar_popped();
|
||||
return popovers.actions_popped() || user_sidebar_popped() || stream_sidebar_popped();
|
||||
};
|
||||
|
||||
exports.hide_all = function () {
|
||||
popovers.hide_actions_popover();
|
||||
popovers.hide_message_info_popover();
|
||||
popovers.hide_stream_sidebar_popover();
|
||||
popovers.hide_user_sidebar_popover();
|
||||
};
|
||||
|
||||
@@ -1003,14 +1003,14 @@ $(function () {
|
||||
message_unhover();
|
||||
});
|
||||
|
||||
$("#main_div").on("mouseover", ".actions_hover", function (e) {
|
||||
$("#main_div").on("mouseover", ".message_sender", function (e) {
|
||||
var row = $(this).closest(".message_row");
|
||||
row.addClass("actions_hovered");
|
||||
row.addClass("sender_name_hovered");
|
||||
});
|
||||
|
||||
$("#main_div").on("mouseout", ".actions_hover", function (e) {
|
||||
$("#main_div").on("mouseout", ".message_sender", function (e) {
|
||||
var row = $(this).closest(".message_row");
|
||||
row.removeClass("actions_hovered");
|
||||
row.removeClass("sender_name_hovered");
|
||||
});
|
||||
|
||||
$("#main_div").on("click", ".star", function (e) {
|
||||
|
||||
@@ -731,14 +731,18 @@ background-color: #feffe0;
|
||||
top: -2px;
|
||||
}
|
||||
|
||||
.actions_hovered .sender_name {
|
||||
.sender_name_hovered .sender_name {
|
||||
color: #0088CC;
|
||||
}
|
||||
|
||||
.actions_hovered .inline_profile_picture {
|
||||
.sender_name_hovered .inline_profile_picture {
|
||||
border-color: #0088CC;
|
||||
}
|
||||
|
||||
.actions_hover:hover {
|
||||
color: #0088CC;
|
||||
}
|
||||
|
||||
.message_label_clickable:hover {
|
||||
cursor: pointer;
|
||||
color: #08C;
|
||||
|
||||
@@ -1,20 +1,7 @@
|
||||
{{! Contents of the "message actions" popup }}
|
||||
<ul class="nav nav-list actions_popover">
|
||||
<div class="popover_info">
|
||||
<li>Sent by <b>{{message.sender_full_name}}</b></li>
|
||||
<li class='my_email'>{{message.sender_email}}</li>
|
||||
<hr />
|
||||
|
||||
<li>{{message.full_date_str}}</li>
|
||||
<li>{{message.full_time_str}}</li>
|
||||
{{#if message.historical}}
|
||||
<li class="small">(Message sent when you were not subscribed)</li>
|
||||
{{/if}}
|
||||
<hr />
|
||||
</div>
|
||||
|
||||
<ul class="nav nav-list actions_popover pull-right">
|
||||
<li>
|
||||
<a class="respond_button">
|
||||
<a href="#" class="respond_button">
|
||||
<i class="icon-share-alt"></i>
|
||||
{{#if message.is_stream}}
|
||||
Reply to this subject on stream <b>{{message.stream}}</b>
|
||||
@@ -25,7 +12,7 @@
|
||||
</li>
|
||||
{{#unless message.is_private}}
|
||||
<li>
|
||||
<a class="respond_personal_button">
|
||||
<a href="#" class="respond_personal_button">
|
||||
<i class="icon-user"></i> Reply to <b>{{message.sender_full_name}}</b> only
|
||||
</a>
|
||||
</li>
|
||||
@@ -33,14 +20,14 @@
|
||||
|
||||
{{#if message.is_stream}}
|
||||
<li>
|
||||
<a class="popover_narrow_by_subject_button" data-msgid="{{message.id}}">
|
||||
<a href="#" class="popover_narrow_by_subject_button" data-msgid="{{message.id}}">
|
||||
<i class="icon-bullhorn"></i>
|
||||
Narrow to this subject on stream <b>{{message.stream}}</b>
|
||||
</a>
|
||||
</li>
|
||||
{{else}}
|
||||
<li>
|
||||
<a class="popover_narrow_by_recipient_button" data-msgid="{{message.id}}">
|
||||
<a href="#" class="popover_narrow_by_recipient_button" data-msgid="{{message.id}}">
|
||||
<i class="icon-user"></i>
|
||||
Narrow to this private message conversation
|
||||
</a>
|
||||
@@ -49,7 +36,7 @@
|
||||
|
||||
{{#if narrowed}}
|
||||
<li>
|
||||
<a class="popover_narrow_by_time_travel_button" data-msgid="{{message.id}}">
|
||||
<a href="#" class="popover_narrow_by_time_travel_button" data-msgid="{{message.id}}">
|
||||
<i class="icon-time"></i> Narrow to messages around this time
|
||||
</a>
|
||||
</li>
|
||||
@@ -57,14 +44,14 @@
|
||||
|
||||
{{#if can_edit_message}}
|
||||
<li>
|
||||
<a class="popover_edit_message" data-msgid="{{message.id}}">
|
||||
<a href="#" class="popover_edit_message" data-msgid="{{message.id}}">
|
||||
<i class="icon-pencil"></i> Edit this message
|
||||
</a>
|
||||
</li>
|
||||
{{/if}}
|
||||
|
||||
<li>
|
||||
<a class="popover_toggle_collapse" data-msgid="{{message.id}}">
|
||||
<a href="#" class="popover_toggle_collapse" data-msgid="{{message.id}}">
|
||||
<i class="{{#if message.collapsed}}icon-plus{{else}}icon-minus{{/if}}"></i>
|
||||
{{#if message.collapsed}}Un-collapse{{else}}Collapse{{/if}} this message
|
||||
</a>
|
||||
|
||||
@@ -61,14 +61,14 @@
|
||||
<td class="messagebox{{^include_sender}} prev_is_same_sender{{/include_sender}}{{^is_stream}} private-message{{/is_stream}}">
|
||||
<div class="message_top_line">
|
||||
{{#include_sender}}
|
||||
<span class="message_sender actions_hover">
|
||||
<span class="message_sender sender_info_hover">
|
||||
{{! See ../js/notifications.js for another user of avatar_url. }}
|
||||
<div class="inline_profile_picture"
|
||||
style="background-image: url('{{small_avatar_url}}');"/>
|
||||
<span class="sender_name">{{sender_full_name}}</span>
|
||||
</span>
|
||||
{{/include_sender}}
|
||||
<span class="message_time actions_hover">{{timestr}}</span>
|
||||
<span class="message_time">{{timestr}}</span>
|
||||
<div class="message_controls">
|
||||
<div class="star">
|
||||
<span class="message_star {{#if starred}}icon-vector-star{{else}}icon-vector-star empty-star{{/if}}"
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
{{! Contents of the "message info" popup }}
|
||||
<ul class="nav nav-list actions_popover">
|
||||
<div class="popover_info">
|
||||
<li>Sent by <b>{{message.sender_full_name}}</b></li>
|
||||
<li class='my_email'>{{message.sender_email}}</li>
|
||||
<hr />
|
||||
|
||||
<li>{{message.full_date_str}}</li>
|
||||
<li>{{message.full_time_str}}</li>
|
||||
{{#if message.historical}}
|
||||
<li class="small">(Message sent when you were not subscribed)</li>
|
||||
{{/if}}
|
||||
<hr />
|
||||
</div>
|
||||
</ul>
|
||||
Reference in New Issue
Block a user