mirror of https://github.com/zulip/zulip.git
Add the new tutorial steps.
(imported from commit 9269acbcf58332002b1d45c0134ccb2db980f05c)
This commit is contained in:
parent
fcf3b262d0
commit
14e27e7583
|
@ -70,6 +70,7 @@ var page_params = {{ page_params }};
|
|||
{% include "zephyr/invite_user.html" %}
|
||||
{% include "zephyr/bankruptcy.html" %}
|
||||
{% include "zephyr/logout.html" %}
|
||||
{% include "zephyr/tutorial_finale.html" %}
|
||||
<div class='notifications top-right'></div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
<div class="modal hide" id="tutorial-finale" tabindex="-1" role="dialog"
|
||||
aria-labelledby="tutorial-finale-label" aria-hidden="true">
|
||||
<div class="modal-header">
|
||||
<h3 id="tutorial-finale-label">Why Humbug?</h3>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<b>We make it easy for you to see the things you care about.</b>
|
||||
|
||||
<p>
|
||||
Streams, subjects, and narrowing let you zoom in on the things that
|
||||
interest you, and quickly ignore the ones that don't.
|
||||
</p>
|
||||
<p>
|
||||
This is critical, because it means you can return to Humbug after being
|
||||
away for hours without missing the important stuff.
|
||||
</p>
|
||||
<p>
|
||||
Now go forth and enjoy Humbug!
|
||||
</p>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button class="btn btn-primary" type="submit" id="tutorial-get-started">Get started</button>
|
||||
</div>
|
||||
</div>
|
|
@ -6,7 +6,7 @@ $(function () {
|
|||
// get_updates completes.
|
||||
if (page_params.have_initial_messages) {
|
||||
util.make_loading_indicator($('#page_loading_indicator'), 'Loading...');
|
||||
} else {
|
||||
} else if (!page_params.needs_tutorial) {
|
||||
util.show_first_run_message();
|
||||
}
|
||||
|
||||
|
|
|
@ -127,6 +127,197 @@ exports.is_running = function() {
|
|||
return is_running;
|
||||
};
|
||||
|
||||
function box(x, y, width, height) {
|
||||
// Blanket everything ouside the box defined by the parameters in a
|
||||
// translucent black screen, and cover the box itself with a clear screen so
|
||||
// nothing in it is clickable.
|
||||
//
|
||||
// x and y are the coordinates for hte upper-left corner of the box.
|
||||
|
||||
var doc_width = $(document).width();
|
||||
var doc_height = $(document).height();
|
||||
|
||||
$("#top-screen").css({opacity: 0.7, width: doc_width, height: y});
|
||||
$("#bottom-screen").offset({top: y + height, left: 0});
|
||||
$("#bottom-screen").css({opacity: 0.7, width: doc_width, height: doc_height});
|
||||
$("#left-screen").offset({top: y, left: 0});
|
||||
$("#left-screen").css({opacity: 0.7, width: x, height: height});
|
||||
$("#right-screen").offset({top: y, left: x + width});
|
||||
$("#right-screen").css({opacity: 0.7, width: x, height: height});
|
||||
$("#clear-screen").css({opacity: 0.0, width: doc_width, height: doc_height});
|
||||
}
|
||||
|
||||
function messages_in_viewport() {
|
||||
var vp = viewport.message_viewport_info();
|
||||
var top = vp.visible_top;
|
||||
var height = vp.visible_height;
|
||||
var last_row = rows.last_visible();
|
||||
|
||||
return $.merge(last_row, last_row.prevAll()).filter(function (idx, row) {
|
||||
var row_offset = $(row).offset();
|
||||
return (row_offset.top > top && row_offset.top < top + height);
|
||||
});
|
||||
}
|
||||
|
||||
function create_and_show_popover(target_div, placement, title, content_template) {
|
||||
target_div.popover({
|
||||
placement: placement,
|
||||
title: templates.render("tutorial_title", {title: title}),
|
||||
content: templates.render(content_template),
|
||||
trigger: "manual"
|
||||
});
|
||||
target_div.popover("show");
|
||||
|
||||
$(".popover").css("z-index", 20001);
|
||||
}
|
||||
|
||||
function finale() {
|
||||
var finale_modal = $("#tutorial-finale");
|
||||
$(".screen").css({opacity: 0.0});
|
||||
finale_modal.css("z-index", 20001);
|
||||
finale_modal.modal("show");
|
||||
|
||||
$("#tutorial-get-started").click(function () {
|
||||
finale_modal.modal("hide");
|
||||
$(".screen").css({opacity: 0.0, width: 0, height: 0});
|
||||
});
|
||||
|
||||
// Restore your actual stream colors and rerender to display any
|
||||
// messages received during the tutorial.
|
||||
set_tutorial_status("finished");
|
||||
is_running = false;
|
||||
current_msg_list.clear();
|
||||
// Force a check on new events before we re-render the message list.
|
||||
force_get_updates();
|
||||
subs.stream_info(real_stream_info);
|
||||
util.show_first_run_message();
|
||||
current_msg_list.rerender();
|
||||
}
|
||||
|
||||
function reply() {
|
||||
var spotlight_message = rows.first_visible().prev(".recipient_row");
|
||||
create_and_show_popover(spotlight_message, "left", "Replying", "tutorial_reply");
|
||||
|
||||
var my_popover = $("#tutorial-reply").closest(".popover");
|
||||
my_popover.offset({left: my_popover.offset().left - 10});
|
||||
|
||||
$("#tutorial-reply-next").click(function () {
|
||||
spotlight_message.popover("destroy");
|
||||
finale();
|
||||
});
|
||||
}
|
||||
|
||||
function home() {
|
||||
var spotlight_message = rows.first_visible().prev(".recipient_row");
|
||||
var x = spotlight_message.offset().left;
|
||||
var y = spotlight_message.offset().top;
|
||||
var height = 0;
|
||||
$.each(messages_in_viewport(), function (idx, row) {
|
||||
height += $(row).height();
|
||||
});
|
||||
|
||||
box(x, y, spotlight_message.width(), height);
|
||||
create_and_show_popover(spotlight_message, "left", "Home view", "tutorial_home");
|
||||
|
||||
var my_popover = $("#tutorial-home").closest(".popover");
|
||||
my_popover.offset({left: my_popover.offset().left - 10});
|
||||
|
||||
$("#tutorial-home-next").click(function () {
|
||||
spotlight_message.popover("destroy");
|
||||
reply();
|
||||
});
|
||||
}
|
||||
|
||||
function private_message() {
|
||||
var bar = rows.first_visible().nextUntil(".private_message").first().next();
|
||||
var spotlight_message = bar.next();
|
||||
var x = bar.offset().left;
|
||||
var y = bar.offset().top;
|
||||
// In the current example we have back-to-back pms.
|
||||
var message_width = bar.width();
|
||||
var message_height = bar.height() + spotlight_message.height() +
|
||||
spotlight_message.next().height();
|
||||
|
||||
box(x, y, message_width, message_height);
|
||||
create_and_show_popover(bar, "top", "Private messages", "tutorial_private");
|
||||
|
||||
var my_popover = $("#tutorial-private").closest(".popover");
|
||||
my_popover.offset({top: my_popover.offset().top - 10,
|
||||
left: bar.offset().left + 76 - my_popover.width() / 2});
|
||||
|
||||
$("#tutorial-private-next").click(function () {
|
||||
bar.popover("destroy");
|
||||
home();
|
||||
});
|
||||
}
|
||||
|
||||
function subject() {
|
||||
var spotlight_message = rows.first_visible();
|
||||
var bar = spotlight_message.prev(".recipient_row");
|
||||
create_and_show_popover(bar, "bottom", "Subjects", "tutorial_subject");
|
||||
|
||||
var my_popover = $("#tutorial-subject").closest(".popover");
|
||||
my_popover.offset({left: bar.offset().left + 94 - my_popover.width() / 2});
|
||||
|
||||
$("#tutorial-subject-next").click(function () {
|
||||
bar.popover("destroy");
|
||||
private_message();
|
||||
});
|
||||
}
|
||||
|
||||
function stream() {
|
||||
var bar = rows.first_visible().prev(".recipient_row");
|
||||
create_and_show_popover(bar, "bottom", "Streams", "tutorial_stream");
|
||||
|
||||
var my_popover = $("#tutorial-stream").closest(".popover");
|
||||
my_popover.offset({left: bar.offset().left + 24 - my_popover.width() / 2});
|
||||
|
||||
$("#tutorial-stream-next").click(function () {
|
||||
bar.popover("destroy");
|
||||
subject();
|
||||
});
|
||||
}
|
||||
|
||||
function message() {
|
||||
var spotlight_message = rows.first_visible();
|
||||
var bar = spotlight_message.prev(".recipient_row");
|
||||
var x = bar.offset().left;
|
||||
var y = bar.offset().top;
|
||||
var message_height = bar.height() + spotlight_message.height();
|
||||
var message_width = bar.width();
|
||||
|
||||
box(x, y, message_width, message_height);
|
||||
create_and_show_popover(bar, "left", "Welcome " + page_params.fullname + "!",
|
||||
"tutorial_message");
|
||||
|
||||
var my_popover = $("#tutorial-message").closest(".popover");
|
||||
my_popover.offset({left: my_popover.offset().left - 10});
|
||||
|
||||
$("#tutorial-message-next").click(function () {
|
||||
bar.popover("destroy");
|
||||
stream();
|
||||
});
|
||||
}
|
||||
|
||||
function welcome() {
|
||||
// Grey out everything.
|
||||
$('#top-screen').css({opacity: 0.7, width: $(document).width(),
|
||||
height: $(document).height()});
|
||||
|
||||
// Highlight the first recipient row.
|
||||
var bar = rows.first_visible().prev(".recipient_row");
|
||||
create_and_show_popover(bar, "left", "Welcome " + page_params.fullname + "!",
|
||||
"tutorial_welcome");
|
||||
|
||||
var my_popover = $("#tutorial-welcome").closest(".popover");
|
||||
my_popover.offset({left: my_popover.offset().left - 10});
|
||||
|
||||
$("#tutorial-welcome-next").click(function () {
|
||||
bar.popover("destroy");
|
||||
message();
|
||||
});
|
||||
}
|
||||
|
||||
exports.start = function () {
|
||||
// If you somehow have messages, temporarily remove them from the visible
|
||||
// feed.
|
||||
|
@ -138,6 +329,7 @@ exports.start = function () {
|
|||
current_msg_list.add_and_rerender(fake_messages);
|
||||
is_running = true;
|
||||
set_tutorial_status("started");
|
||||
welcome();
|
||||
};
|
||||
|
||||
exports.initialize = function () {
|
||||
|
|
|
@ -40,6 +40,8 @@ var furthest_read = -1;
|
|||
var server_furthest_read = -1;
|
||||
var pointer_update_in_flight = false;
|
||||
|
||||
var events_stored_during_tutorial = [];
|
||||
|
||||
function add_person(person) {
|
||||
page_params.people_list.push(person);
|
||||
people_dict[person.email] = person;
|
||||
|
@ -812,6 +814,16 @@ function get_updates_success(data) {
|
|||
var messages_to_update = [];
|
||||
var new_pointer;
|
||||
|
||||
if (tutorial.is_running()) {
|
||||
events_stored_during_tutorial = events_stored_during_tutorial.concat(data.events);
|
||||
return;
|
||||
}
|
||||
|
||||
if (events_stored_during_tutorial.length > 0) {
|
||||
data.events = events_stored_during_tutorial.concat(data.events);
|
||||
events_stored_during_tutorial = [];
|
||||
}
|
||||
|
||||
$.each(data.events, function (idx, event) {
|
||||
get_updates_params.last_event_id = Math.max(get_updates_params.last_event_id,
|
||||
event.id);
|
||||
|
@ -955,7 +967,12 @@ function get_updates(options) {
|
|||
$('#connection-error').hide();
|
||||
|
||||
get_updates_success(data);
|
||||
get_updates_timeout = setTimeout(get_updates, 0);
|
||||
|
||||
if (tutorial.is_running()) {
|
||||
get_updates_timeout = setTimeout(get_updates, 5000);
|
||||
} else {
|
||||
get_updates_timeout = setTimeout(get_updates, 0);
|
||||
}
|
||||
},
|
||||
error: function (xhr, error_type, exn) {
|
||||
// If we are old enough to have messages outside of the
|
||||
|
|
|
@ -1973,3 +1973,18 @@ li.expanded_subject {
|
|||
background: #000;
|
||||
z-index: 20000;
|
||||
}
|
||||
|
||||
.tutorial-popover {
|
||||
width: 200px;
|
||||
}
|
||||
|
||||
#tutorial-stream {
|
||||
width: 250px;
|
||||
}
|
||||
|
||||
#tutorial-subject {
|
||||
width: 250px;
|
||||
}
|
||||
.tutorial-done-button {
|
||||
text-align: right;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
{{! Contents of the "tutorial home" onboarding popup }}
|
||||
|
||||
<div class="tutorial-popover" id="tutorial-home">
|
||||
|
||||
<p>
|
||||
We show stream and private messages together, and time flows down. You
|
||||
can "narrow" to a particular stream or subject by clicking on it.
|
||||
</p>
|
||||
|
||||
<div class="tutorial-done-button">
|
||||
<button class="btn btn-primary" type="submit" id="tutorial-home-next">Next</button>
|
||||
</div>
|
||||
</div>
|
|
@ -0,0 +1,11 @@
|
|||
{{! Contents of the "tutorial message" onboarding popup }}
|
||||
|
||||
<div class="tutorial-popover" id="tutorial-message">
|
||||
<p>
|
||||
Messages in Humbug go to a <b>stream</b> and have a <b>subject</b>.
|
||||
</p>
|
||||
|
||||
<div class="tutorial-done-button">
|
||||
<button class="btn btn-primary" type="submit" id="tutorial-message-next">Next</button>
|
||||
</div>
|
||||
</div>
|
|
@ -0,0 +1,12 @@
|
|||
{{! Contents of the "tutorial private" onboarding popup }}
|
||||
|
||||
<div id="tutorial-private">
|
||||
|
||||
<p>
|
||||
You can also send private messages to one or more people.
|
||||
</p>
|
||||
|
||||
<div class="tutorial-done-button">
|
||||
<button class="btn btn-primary" type="submit" id="tutorial-private-next">Next</button>
|
||||
</div>
|
||||
</div>
|
|
@ -0,0 +1,13 @@
|
|||
{{! Contents of the "tutorial reply" onboarding popup }}
|
||||
|
||||
<div class="tutorial-popover" id="tutorial-reply">
|
||||
|
||||
<p>
|
||||
You can reply to any message by clicking on it. The stream and subject
|
||||
will automatically be filled in.
|
||||
</p>
|
||||
|
||||
<div class="tutorial-done-button">
|
||||
<button class="btn btn-primary" type="submit" id="tutorial-reply-next">Next</button>
|
||||
</div>
|
||||
</div>
|
|
@ -0,0 +1,11 @@
|
|||
{{! Contents of the "tutorial stream" onboarding popup }}
|
||||
|
||||
<div class="tutorial-popover" id="tutorial-stream">
|
||||
<p>
|
||||
Streams are like chat rooms or mailing lists. You can easily join, leave, and make them.
|
||||
</p>
|
||||
|
||||
<div class="tutorial-done-button">
|
||||
<button class="btn btn-primary" type="submit" id="tutorial-stream-next">Next</button>
|
||||
</div>
|
||||
</div>
|
|
@ -0,0 +1,13 @@
|
|||
{{! Contents of the "tutorial subject" onboarding popup }}
|
||||
|
||||
<div class="tutorial-popover" id="tutorial-subject">
|
||||
|
||||
<p>
|
||||
A subject is one word that describes what this message is about. Just
|
||||
like an e-mail subject line, only much shorter. Don't overthink it.
|
||||
</p>
|
||||
|
||||
<div class="tutorial-done-button">
|
||||
<button class="btn btn-primary" type="submit" id="tutorial-subject-next">Next</button>
|
||||
</div>
|
||||
</div>
|
|
@ -0,0 +1,3 @@
|
|||
{{! Contents of the tutorial popup title}}
|
||||
|
||||
<h4>{{title}}</h4>
|
|
@ -0,0 +1,11 @@
|
|||
{{! Contents of the "tutorial welcome" onboarding popup }}
|
||||
|
||||
<div class="tutorial-popover" id="tutorial-welcome">
|
||||
<p>
|
||||
Humbug isn't like other chat tools. Here are some things you need to know.
|
||||
</p>
|
||||
|
||||
<div class="tutorial-done-button">
|
||||
<button class="btn btn-primary" type="submit" id="tutorial-welcome-next">Next</button>
|
||||
</div>
|
||||
</div>
|
Loading…
Reference in New Issue