2012-11-16 16:45:39 +01:00
|
|
|
var ui = (function () {
|
|
|
|
|
|
|
|
var exports = {};
|
|
|
|
|
2013-07-16 20:00:47 +02:00
|
|
|
var actively_scrolling = false;
|
|
|
|
|
2016-04-10 14:15:47 +02:00
|
|
|
exports.have_scrolled_away_from_top = true;
|
|
|
|
|
2013-07-16 20:00:47 +02:00
|
|
|
exports.actively_scrolling = function () {
|
|
|
|
return actively_scrolling;
|
|
|
|
};
|
|
|
|
|
2012-12-03 20:54:29 +01:00
|
|
|
// What, if anything, obscures the home tab?
|
2012-11-30 18:28:23 +01:00
|
|
|
|
2013-07-23 00:25:25 +02:00
|
|
|
exports.replace_emoji_with_text = function (element) {
|
|
|
|
element.find(".emoji").replaceWith(function () {
|
|
|
|
return $(this).attr("alt");
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
2013-12-19 17:03:08 +01:00
|
|
|
function update_message_in_all_views(message_id, callback) {
|
2016-04-25 23:45:25 +02:00
|
|
|
_.each([message_list.all, home_msg_list, message_list.narrowed], function (list) {
|
2013-12-19 17:03:08 +01:00
|
|
|
if (list === undefined) {
|
2013-03-27 18:30:02 +01:00
|
|
|
return;
|
|
|
|
}
|
2013-12-19 17:03:08 +01:00
|
|
|
var row = list.get_row(message_id);
|
2013-03-27 18:30:02 +01:00
|
|
|
if (row === undefined) {
|
2013-12-19 17:03:08 +01:00
|
|
|
// The row may not exist, e.g. if you do an action on a message in
|
|
|
|
// a narrowed view
|
2013-03-27 18:30:02 +01:00
|
|
|
return;
|
|
|
|
}
|
2013-12-19 17:03:08 +01:00
|
|
|
callback(row);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2014-03-14 15:30:29 +01:00
|
|
|
exports.find_message = function (message_id) {
|
2014-01-28 22:44:34 +01:00
|
|
|
// Try to find the message object. It might be in the narrow list
|
2016-04-21 22:49:23 +02:00
|
|
|
// (if it was loaded when narrowed), or only in the message_list.all
|
2014-01-28 22:44:34 +01:00
|
|
|
// (if received from the server while in a different narrow)
|
|
|
|
var message;
|
2016-04-25 23:45:25 +02:00
|
|
|
_.each([message_list.all, home_msg_list, message_list.narrowed], function (msg_list) {
|
2014-01-28 22:44:34 +01:00
|
|
|
if (msg_list !== undefined && message === undefined) {
|
|
|
|
message = msg_list.get(message_id);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
return message;
|
2014-03-14 15:30:29 +01:00
|
|
|
};
|
2014-01-28 22:44:34 +01:00
|
|
|
|
2013-12-19 17:03:08 +01:00
|
|
|
exports.update_starred = function (message_id, starred) {
|
|
|
|
// Update the message object pointed to by the various message
|
|
|
|
// lists.
|
2014-03-14 15:30:29 +01:00
|
|
|
var message = exports.find_message(message_id);
|
2013-12-19 17:03:08 +01:00
|
|
|
|
2017-01-23 05:38:57 +01:00
|
|
|
// If it isn't cached in the browser, no need to do anything
|
|
|
|
if (message === undefined) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2017-03-18 01:41:56 +01:00
|
|
|
unread_ops.mark_message_as_read(message);
|
2013-12-19 17:03:08 +01:00
|
|
|
|
2014-01-30 18:08:02 +01:00
|
|
|
message.starred = starred;
|
2013-12-19 17:03:08 +01:00
|
|
|
|
|
|
|
// Avoid a full re-render, but update the star in each message
|
|
|
|
// table in which it is visible.
|
|
|
|
update_message_in_all_views(message_id, function update_row(row) {
|
2017-02-23 23:33:57 +01:00
|
|
|
var elt = row.find(".star");
|
2014-01-23 17:52:28 +01:00
|
|
|
if (starred) {
|
|
|
|
elt.addClass("icon-vector-star").removeClass("icon-vector-star-empty").removeClass("empty-star");
|
|
|
|
} else {
|
|
|
|
elt.removeClass("icon-vector-star").addClass("icon-vector-star-empty").addClass("empty-star");
|
|
|
|
}
|
2013-04-14 05:04:47 +02:00
|
|
|
var title_state = message.starred ? "Unstar" : "Star";
|
2014-01-23 17:52:28 +01:00
|
|
|
elt.attr("title", title_state + " this message");
|
2013-03-27 18:30:02 +01:00
|
|
|
});
|
2014-01-23 17:52:28 +01:00
|
|
|
};
|
2013-03-27 18:30:02 +01:00
|
|
|
|
2013-12-19 17:03:08 +01:00
|
|
|
var local_messages_to_show = [];
|
|
|
|
var show_message_timestamps = _.throttle(function () {
|
|
|
|
_.each(local_messages_to_show, function (message_id) {
|
|
|
|
update_message_in_all_views(message_id, function update_row(row) {
|
|
|
|
row.find('.message_time').toggleClass('notvisible', false);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
local_messages_to_show = [];
|
|
|
|
}, 100);
|
|
|
|
|
|
|
|
exports.show_local_message_arrived = function (message_id) {
|
|
|
|
local_messages_to_show.push(message_id);
|
|
|
|
show_message_timestamps();
|
|
|
|
};
|
|
|
|
|
2014-01-02 17:34:16 +01:00
|
|
|
exports.show_message_failed = function (message_id, failed_msg) {
|
2013-12-19 17:03:08 +01:00
|
|
|
// Failed to send message, so display inline retry/cancel
|
|
|
|
update_message_in_all_views(message_id, function update_row(row) {
|
2014-01-02 17:34:16 +01:00
|
|
|
var failed_div = row.find('.message_failed');
|
|
|
|
failed_div.toggleClass('notvisible', false);
|
|
|
|
failed_div.find('.failed_text').attr('title', failed_msg);
|
2013-12-19 17:03:08 +01:00
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
exports.show_failed_message_success = function (message_id) {
|
|
|
|
// Previously failed message succeeded
|
|
|
|
update_message_in_all_views(message_id, function update_row(row) {
|
|
|
|
row.find('.message_failed').toggleClass('notvisible', true);
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
2017-01-30 20:55:39 +01:00
|
|
|
$(document).ready(function () {
|
|
|
|
var info_overlay_toggle = components.toggle({
|
|
|
|
name: "info-overlay-toggle",
|
|
|
|
selected: 0,
|
|
|
|
values: [
|
2017-01-30 21:55:06 +01:00
|
|
|
{ label: "Keyboard shortcuts", key: "keyboard-shortcuts" },
|
|
|
|
{ label: "Message formatting", key: "markdown-help" },
|
|
|
|
{ label: "Search operators", key: "search-operators" },
|
2017-01-30 20:55:39 +01:00
|
|
|
],
|
2017-01-30 21:55:06 +01:00
|
|
|
callback: function (name, key) {
|
|
|
|
$(".overlay-modal").hide();
|
|
|
|
$("#" + key).show();
|
|
|
|
},
|
2017-01-30 20:55:39 +01:00
|
|
|
}).get();
|
|
|
|
|
|
|
|
$(".informational-overlays .overlay-tabs")
|
|
|
|
.append($(info_overlay_toggle).addClass("large"));
|
|
|
|
});
|
|
|
|
|
2017-01-05 21:11:45 +01:00
|
|
|
exports.show_info_overlay = function (target) {
|
|
|
|
var el = {
|
|
|
|
overlay: $(".informational-overlays"),
|
|
|
|
};
|
|
|
|
|
|
|
|
if (!el.overlay.hasClass("show")) {
|
|
|
|
$(el.overlay).addClass("show");
|
|
|
|
}
|
|
|
|
|
2017-01-30 21:55:06 +01:00
|
|
|
if (target) {
|
|
|
|
components.toggle.lookup("info-overlay-toggle").goto(target);
|
|
|
|
}
|
2017-01-05 21:11:45 +01:00
|
|
|
};
|
|
|
|
|
2013-01-16 19:50:18 +01:00
|
|
|
var loading_more_messages_indicator_showing = false;
|
|
|
|
exports.show_loading_more_messages_indicator = function () {
|
|
|
|
if (! loading_more_messages_indicator_showing) {
|
2014-03-13 15:03:01 +01:00
|
|
|
loading.make_indicator($('#loading_more_messages_indicator'),
|
2013-07-12 18:31:26 +02:00
|
|
|
{abs_positioned: true});
|
2013-01-16 19:50:18 +01:00
|
|
|
loading_more_messages_indicator_showing = true;
|
2014-03-13 21:14:33 +01:00
|
|
|
floating_recipient_bar.hide();
|
2012-11-28 22:17:57 +01:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2013-01-16 19:50:18 +01:00
|
|
|
exports.hide_loading_more_messages_indicator = function () {
|
|
|
|
if (loading_more_messages_indicator_showing) {
|
2014-03-13 15:03:01 +01:00
|
|
|
loading.destroy_indicator($("#loading_more_messages_indicator"));
|
2013-01-16 19:50:18 +01:00
|
|
|
loading_more_messages_indicator_showing = false;
|
2012-11-28 22:17:57 +01:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2013-12-04 17:54:45 +01:00
|
|
|
/* EXPERIMENTS */
|
|
|
|
|
2013-12-05 20:23:02 +01:00
|
|
|
/* This method allows an advanced user to use the console
|
|
|
|
* to switch the application to span full width of the browser.
|
|
|
|
*/
|
|
|
|
exports.switchToFullWidth = function () {
|
|
|
|
$("#full-width-style").remove();
|
|
|
|
$('head').append('<style id="full-width-style" type="text/css">' +
|
|
|
|
'#home .alert-bar, .recipient-bar-content, #compose-container, .app-main, .header-main { max-width: none; }' +
|
|
|
|
'</style>');
|
|
|
|
return ("Switched to full width");
|
|
|
|
};
|
|
|
|
|
2013-12-04 17:54:45 +01:00
|
|
|
/* END OF EXPERIMENTS */
|
|
|
|
|
2013-08-02 23:41:40 +02:00
|
|
|
function scroll_finished() {
|
|
|
|
actively_scrolling = false;
|
|
|
|
|
|
|
|
if ($('#home').hasClass('active')) {
|
2016-04-12 17:38:47 +02:00
|
|
|
if (!pointer.suppress_scroll_pointer_update) {
|
2017-03-18 22:46:36 +01:00
|
|
|
message_viewport.keep_pointer_in_view();
|
2013-08-02 23:41:40 +02:00
|
|
|
} else {
|
2016-04-12 17:38:47 +02:00
|
|
|
pointer.suppress_scroll_pointer_update = false;
|
2013-08-02 23:41:40 +02:00
|
|
|
}
|
2014-03-13 21:14:33 +01:00
|
|
|
floating_recipient_bar.update();
|
2017-03-10 23:48:51 +01:00
|
|
|
if (message_viewport.scrollTop() === 0 &&
|
2016-04-10 14:15:47 +02:00
|
|
|
ui.have_scrolled_away_from_top) {
|
|
|
|
ui.have_scrolled_away_from_top = false;
|
2017-03-19 18:19:48 +01:00
|
|
|
message_fetch.load_more_messages(current_msg_list);
|
2016-04-10 14:15:47 +02:00
|
|
|
} else if (!ui.have_scrolled_away_from_top) {
|
|
|
|
ui.have_scrolled_away_from_top = true;
|
2013-08-02 23:41:40 +02:00
|
|
|
}
|
|
|
|
// When the window scrolls, it may cause some messages to
|
|
|
|
// enter the screen and become read. Calling
|
2017-03-18 01:41:56 +01:00
|
|
|
// unread_ops.process_visible will update necessary
|
2013-08-02 23:41:40 +02:00
|
|
|
// data structures and DOM elements.
|
2017-03-18 01:41:56 +01:00
|
|
|
setTimeout(unread_ops.process_visible, 0);
|
2013-08-02 23:41:40 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
var scroll_timer;
|
|
|
|
function scroll_finish() {
|
|
|
|
actively_scrolling = true;
|
|
|
|
clearTimeout(scroll_timer);
|
|
|
|
scroll_timer = setTimeout(scroll_finished, 100);
|
|
|
|
}
|
|
|
|
|
2013-02-18 08:16:57 +01:00
|
|
|
// Save the compose content cursor position and restore when we
|
|
|
|
// shift-tab back in (see hotkey.js).
|
|
|
|
var saved_compose_cursor = 0;
|
|
|
|
|
|
|
|
$(function () {
|
2017-03-10 23:48:51 +01:00
|
|
|
message_viewport.message_pane.scroll($.throttle(50, function () {
|
2017-03-18 01:41:56 +01:00
|
|
|
unread_ops.process_visible();
|
2014-01-31 00:00:33 +01:00
|
|
|
scroll_finish();
|
|
|
|
}));
|
|
|
|
|
2013-02-18 08:16:57 +01:00
|
|
|
$('#new_message_content').blur(function () {
|
2016-06-14 22:49:41 +02:00
|
|
|
saved_compose_cursor = $(this).caret();
|
2013-02-18 08:16:57 +01:00
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
exports.restore_compose_cursor = function () {
|
|
|
|
$('#new_message_content')
|
|
|
|
.focus()
|
2016-06-14 22:49:41 +02:00
|
|
|
.caret(saved_compose_cursor);
|
2013-02-18 08:16:57 +01:00
|
|
|
};
|
2013-07-24 19:43:45 +02:00
|
|
|
|
2013-08-09 21:46:34 +02:00
|
|
|
$(function () {
|
|
|
|
if (window.bridge !== undefined) {
|
2013-08-27 22:07:59 +02:00
|
|
|
// Disable "spellchecking" in our desktop app. The "spellchecking"
|
|
|
|
// in our Mac app is actually autocorrect, and frustrates our
|
|
|
|
// users.
|
2013-08-09 21:46:34 +02:00
|
|
|
$("#new_message_content").attr('spellcheck', 'false');
|
2013-08-27 22:07:59 +02:00
|
|
|
// Modify the zephyr mirroring error message in our desktop
|
|
|
|
// app, since it doesn't work from the desktop version.
|
|
|
|
$("#webathena_login_menu").hide();
|
|
|
|
$("#normal-zephyr-mirror-error-text").addClass("notdisplayed");
|
|
|
|
$("#desktop-zephyr-mirror-error-text").removeClass("notdisplayed");
|
2013-08-09 21:46:34 +02:00
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2012-11-16 16:45:39 +01:00
|
|
|
return exports;
|
|
|
|
}());
|
2016-12-29 12:23:07 +01:00
|
|
|
|
|
|
|
if (typeof module !== 'undefined') {
|
|
|
|
module.exports = ui;
|
|
|
|
}
|