Add support for loading a narrows-only embedded Zulip window.

Features:
* Only shows messages in the narrow
* New messages in the narrow will arrive as they are sent
* Works even for streams you're not subscribed to
* Automatically subscribes you to a stream on send
* Doesn't update your pointer
* All searches etc. automatically have the narrow added

(imported from commit 2e12b76849f6ca0f53dda5985dad477a04f7bbac)
This commit is contained in:
Tim Abbott
2013-12-13 14:20:28 -05:00
parent 8e6728f206
commit 2276c6e524
7 changed files with 60 additions and 21 deletions

View File

@@ -563,12 +563,16 @@ exports.has_message_content = function () {
// *Synchronously* check if a stream exists.
exports.check_stream_existence = function (stream_name) {
exports.check_stream_existence = function (stream_name, autosubscribe) {
var result = "error";
var request = {'stream': stream_name};
if (autosubscribe) {
request.autosubscribe = true;
}
$.ajax({
type: "POST",
url: "/json/subscriptions/exists",
data: {'stream': stream_name},
data: request,
async: false,
success: function (data) {
if (data.subscribed) {
@@ -591,8 +595,8 @@ exports.check_stream_existence = function (stream_name) {
// Checks if a stream exists. If not, displays an error and returns
// false.
function check_stream_for_send(stream_name) {
var result = exports.check_stream_existence(stream_name);
function check_stream_for_send(stream_name, autosubscribe) {
var result = exports.check_stream_existence(stream_name, autosubscribe);
if (result === "error") {
compose_error("Error checking subscription", $("#stream"));
@@ -621,7 +625,7 @@ function validate_stream_message() {
var response;
if (!stream_data.is_subscribed(stream_name)) {
switch(check_stream_for_send(stream_name)) {
switch(check_stream_for_send(stream_name, page_params.narrow_stream !== undefined)) {
case "does-not-exist":
response = "<p>The stream <b>" +
Handlebars.Utils.escapeExpression(stream_name) + "</b> does not exist.</p>" +

View File

@@ -36,7 +36,9 @@ function mit_edu_topic_name_match(message, operand) {
}
function message_in_home(message) {
if (message.type === "private" || message.mentioned) {
if (message.type === "private" || message.mentioned ||
(page_params.narrow_stream !== undefined &&
message.stream.toLowerCase() === page_params.narrow_stream.toLowerCase())) {
return true;
}
@@ -178,12 +180,12 @@ Filter.prototype = {
public_operators: function Filter_public_operators() {
var safe_to_return = _.filter(this._operators, function (value) {
// Currently just filter out the "in" keyword.
return value[0] !== 'in';
// Filter out the "in" keyword and the embedded narrow (if any).
return value[0] !== 'in' && !(page_params.narrow_stream !== undefined &&
value[0] === "stream" &&
value[1].toLowerCase() === page_params.narrow_stream.toLowerCase());
});
if (safe_to_return.length !== 0) {
return safe_to_return;
}
return safe_to_return;
},
operands: function Filter_get_operands(operator) {

View File

@@ -26,7 +26,7 @@ exports.predicate = function () {
exports.operators = function () {
if (current_filter === undefined) {
return [];
return page_params.narrow;
}
return current_filter.operators();
};

View File

@@ -1126,7 +1126,14 @@ function load_old_messages(opts) {
num_after: opts.num_after};
if (opts.msg_list.narrowed && narrow.active()) {
data.narrow = JSON.stringify(narrow.public_operators());
var operators = narrow.public_operators();
if (page_params.narrow !== undefined) {
operators = operators.concat(page_params.narrow);
}
data.narrow = JSON.stringify(operators);
}
if (opts.msg_list === home_msg_list && page_params.narrow_stream !== undefined) {
data.narrow = JSON.stringify([["stream", page_params.narrow_stream]]);
}
$.ajax({
@@ -1295,8 +1302,8 @@ function main() {
keepTracking: true});
$(document).on('message_selected.zulip', function (event) {
if ((event.msg_list === home_msg_list) || (event.msg_list === all_msg_list)) {
// Only advance the pointer when not narrowed
if (event.msg_list === home_msg_list && page_params.narrow_stream === undefined) {
if (event.id > furthest_read) {
furthest_read = event.id;
}

View File

@@ -288,7 +288,7 @@ def get_client_descriptors_for_realm_all_streams(realm_id):
def add_to_client_dicts(client):
user_clients.setdefault(client.user_profile_id, []).append(client)
if client.all_public_streams:
if client.all_public_streams or client.narrow != []:
realm_clients_all_streams.setdefault(client.realm_id, []).append(client)
def allocate_client_descriptor(user_profile_id, realm_id, event_types, client_type,

View File

@@ -44,7 +44,7 @@ var Filter = require('js/filter.js');
operators = [['in', 'all']];
filter = new Filter(operators);
assert.deepEqual(filter.public_operators(), undefined);
assert.deepEqual(filter.public_operators(), []);
}());
(function test_canonicalizations() {

View File

@@ -732,8 +732,19 @@ def home(request):
request._email = request.user.email
request.client = get_client("website")
narrow = []
narrow_stream = None
if request.GET.get("narrow"):
try:
narrow_stream = get_stream(request.GET.get("narrow"), user_profile.realm)
assert(narrow_stream is not None)
assert(narrow_stream.is_public())
narrow = [["stream", narrow_stream.name]]
except Exception:
logging.exception("Narrow parsing")
register_ret = do_events_register(user_profile, request.client,
apply_markdown=True)
apply_markdown=True, narrow=narrow)
user_has_messages = (register_ret['max_message_id'] != -1)
# Reset our don't-spam-users-with-email counter since the
@@ -817,6 +828,18 @@ def home(request):
autoscroll_forever = user_profile.autoscroll_forever,
show_autoscroll_forever_option = user_profile.realm.domain in ("customer28.invalid", "zulip.com")
)
if narrow_stream is not None:
# In narrow_stream context, initial pointer is just latest message
recipient = get_recipient(Recipient.STREAM, narrow_stream.id)
try:
initial_pointer = Message.objects.filter(recipient=recipient).order_by('id').reverse()[0].id
except IndexError:
initial_pointer = -1
page_params["narrow_stream"] = narrow_stream.name
page_params["narrow"] = narrow
page_params["max_message_id"] = initial_pointer
page_params["initial_pointer"] = initial_pointer
page_params["have_initial_messages"] = (initial_pointer != -1)
statsd.incr('views.home')
show_invites = True
@@ -1908,16 +1931,19 @@ def json_change_ui_settings(request, user_profile,
@authenticated_json_post_view
@has_request_variables
def json_stream_exists(request, user_profile, stream=REQ):
return stream_exists_backend(request, user_profile, stream)
def json_stream_exists(request, user_profile, stream=REQ,
autosubscribe=REQ(default=False)):
return stream_exists_backend(request, user_profile, stream, autosubscribe)
def stream_exists_backend(request, user_profile, stream_name):
def stream_exists_backend(request, user_profile, stream_name, autosubscribe):
if not valid_stream_name(stream_name):
return json_error("Invalid characters in stream name")
stream = get_stream(stream_name, user_profile.realm)
result = {"exists": bool(stream)}
if stream is not None:
recipient = get_recipient(Recipient.STREAM, stream.id)
if autosubscribe:
bulk_add_subscriptions([stream], [user_profile])
result["subscribed"] = Subscription.objects.filter(user_profile=user_profile,
recipient=recipient,
active=True).exists()