2020-05-16 13:13:59 +02:00
|
|
|
const settings_config = require("./settings_config");
|
|
|
|
|
2017-05-31 08:53:09 +02:00
|
|
|
exports.dispatch_normal_event = function dispatch_normal_event(event) {
|
2019-11-02 00:06:25 +01:00
|
|
|
const noop = function () {};
|
2017-05-31 08:53:09 +02:00
|
|
|
switch (event.type) {
|
|
|
|
case 'alert_words':
|
2018-08-04 08:25:43 +02:00
|
|
|
alert_words.set_words(event.alert_words);
|
2017-06-11 20:30:09 +02:00
|
|
|
alert_words_ui.render_alert_words_ui();
|
2017-05-31 08:53:09 +02:00
|
|
|
break;
|
|
|
|
|
2018-05-04 22:57:36 +02:00
|
|
|
case 'attachment':
|
2018-05-05 00:48:29 +02:00
|
|
|
attachments_ui.update_attachments(event);
|
2018-05-04 22:57:36 +02:00
|
|
|
break;
|
|
|
|
|
2018-08-25 13:08:24 +02:00
|
|
|
case 'custom_profile_fields':
|
|
|
|
page_params.custom_profile_fields = event.fields;
|
|
|
|
settings_profile_fields.populate_profile_fields(page_params.custom_profile_fields);
|
|
|
|
settings_account.add_custom_profile_fields_to_settings();
|
|
|
|
break;
|
|
|
|
|
2017-05-31 08:53:09 +02:00
|
|
|
case 'default_streams':
|
2017-08-22 18:20:00 +02:00
|
|
|
stream_data.set_realm_default_streams(event.default_streams);
|
2017-05-31 08:53:09 +02:00
|
|
|
settings_streams.update_default_streams_table();
|
|
|
|
break;
|
|
|
|
|
2019-10-25 23:55:37 +02:00
|
|
|
case 'delete_message': {
|
2020-06-11 12:12:12 +02:00
|
|
|
const msg_ids = event.message_ids;
|
2018-08-25 13:08:24 +02:00
|
|
|
// message is passed to unread.get_unread_messages,
|
|
|
|
// which returns all the unread messages out of a given list.
|
|
|
|
// So double marking something as read would not occur
|
2020-06-11 12:12:12 +02:00
|
|
|
unread_ops.process_read_messages_event(msg_ids);
|
|
|
|
|
2018-08-25 13:08:24 +02:00
|
|
|
if (event.message_type === 'stream') {
|
2020-06-15 19:52:00 +02:00
|
|
|
stream_topic_history.remove_messages({
|
2018-08-25 13:08:24 +02:00
|
|
|
stream_id: event.stream_id,
|
|
|
|
topic_name: event.topic,
|
2020-06-11 12:12:12 +02:00
|
|
|
num_messages: msg_ids.length,
|
2018-08-25 13:08:24 +02:00
|
|
|
});
|
|
|
|
stream_list.update_streams_sidebar();
|
|
|
|
}
|
2020-06-11 12:12:12 +02:00
|
|
|
|
2020-06-12 11:21:35 +02:00
|
|
|
ui.remove_messages(msg_ids);
|
2018-08-25 13:08:24 +02:00
|
|
|
break;
|
2019-10-25 23:55:37 +02:00
|
|
|
}
|
2018-08-25 13:08:24 +02:00
|
|
|
|
2019-11-16 09:26:28 +01:00
|
|
|
case 'has_zoom_token':
|
|
|
|
page_params.has_zoom_token = event.value;
|
|
|
|
if (event.value) {
|
|
|
|
for (const callback of compose.zoom_token_callbacks.values()) {
|
|
|
|
callback();
|
|
|
|
}
|
|
|
|
compose.zoom_token_callbacks.clear();
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2017-05-31 08:53:09 +02:00
|
|
|
case 'hotspots':
|
2017-07-14 03:21:30 +02:00
|
|
|
hotspots.load_new(event.hotspots);
|
|
|
|
page_params.hotspots = page_params.hotspots ?
|
|
|
|
page_params.hotspots.concat(event.hotspots) :
|
|
|
|
event.hotspots;
|
2017-05-31 08:53:09 +02:00
|
|
|
break;
|
|
|
|
|
2017-12-14 22:22:17 +01:00
|
|
|
case 'invites_changed':
|
|
|
|
if ($('#admin-invites-list').length) {
|
2019-02-15 19:09:25 +01:00
|
|
|
settings_invites.set_up(false);
|
2017-12-14 22:22:17 +01:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2017-05-31 08:53:09 +02:00
|
|
|
case 'muted_topics':
|
|
|
|
muting_ui.handle_updates(event.muted_topics);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 'presence':
|
2020-02-03 16:25:13 +01:00
|
|
|
activity.update_presence_info(event.user_id, event.presence, event.server_timestamp);
|
2017-05-31 08:53:09 +02:00
|
|
|
break;
|
|
|
|
|
2019-10-25 23:55:37 +02:00
|
|
|
case 'restart': {
|
2019-11-02 00:06:25 +01:00
|
|
|
const reload_options = {
|
2018-05-07 01:38:14 +02:00
|
|
|
save_pointer: true,
|
|
|
|
save_narrow: true,
|
|
|
|
save_compose: true,
|
|
|
|
message: "The application has been updated; reloading!",
|
|
|
|
};
|
2017-05-31 08:53:09 +02:00
|
|
|
if (event.immediate) {
|
|
|
|
reload_options.immediate = true;
|
|
|
|
}
|
|
|
|
reload.initiate(reload_options);
|
|
|
|
break;
|
2019-10-25 23:55:37 +02:00
|
|
|
}
|
2017-05-31 08:53:09 +02:00
|
|
|
|
|
|
|
case 'reaction':
|
|
|
|
if (event.op === 'add') {
|
|
|
|
reactions.add_reaction(event);
|
|
|
|
} else if (event.op === 'remove') {
|
|
|
|
reactions.remove_reaction(event);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2019-10-25 23:55:37 +02:00
|
|
|
case 'realm': {
|
2019-11-02 00:06:25 +01:00
|
|
|
const realm_settings = {
|
2017-07-18 02:58:13 +02:00
|
|
|
add_emoji_by_admins_only: settings_emoji.update_custom_emoji_ui,
|
|
|
|
allow_edit_history: noop,
|
2017-11-08 13:40:46 +01:00
|
|
|
allow_message_deleting: noop,
|
2017-08-20 03:08:53 +02:00
|
|
|
allow_message_editing: noop,
|
2018-04-21 19:30:32 +02:00
|
|
|
allow_community_topic_editing: noop,
|
2019-11-02 17:58:55 +01:00
|
|
|
user_group_edit_policy: noop,
|
2019-04-23 04:51:04 +02:00
|
|
|
avatar_changes_disabled: settings_account.update_avatar_change_display,
|
2018-01-29 16:10:54 +01:00
|
|
|
bot_creation_policy: settings_bots.update_bot_permissions_ui,
|
2019-05-06 16:34:31 +02:00
|
|
|
create_stream_policy: noop,
|
2019-04-08 19:23:00 +02:00
|
|
|
invite_to_stream_policy: noop,
|
2020-04-10 09:38:55 +02:00
|
|
|
default_code_block_language: noop,
|
2018-03-30 19:47:27 +02:00
|
|
|
default_language: noop,
|
2018-03-30 22:38:16 +02:00
|
|
|
default_twenty_four_hour_time: noop,
|
2018-03-30 19:47:27 +02:00
|
|
|
description: noop,
|
2019-04-06 06:34:49 +02:00
|
|
|
digest_emails_enabled: noop,
|
2019-03-31 12:13:42 +02:00
|
|
|
digest_weekday: noop,
|
2018-08-03 22:52:21 +02:00
|
|
|
email_address_visibility: noop,
|
2018-03-02 21:44:14 +01:00
|
|
|
email_changes_disabled: settings_account.update_email_change_display,
|
2018-03-05 19:19:19 +01:00
|
|
|
disallow_disposable_email_addresses: noop,
|
2017-07-18 02:58:13 +02:00
|
|
|
inline_image_preview: noop,
|
|
|
|
inline_url_embed_preview: noop,
|
|
|
|
invite_by_admins_only: noop,
|
|
|
|
invite_required: noop,
|
|
|
|
mandatory_topics: noop,
|
2018-03-25 15:35:10 +02:00
|
|
|
message_content_edit_limit_seconds: noop,
|
2017-11-26 09:12:10 +01:00
|
|
|
message_content_delete_limit_seconds: noop,
|
2018-03-30 19:47:27 +02:00
|
|
|
message_retention_days: noop,
|
2017-07-18 02:58:13 +02:00
|
|
|
name: notifications.redraw_title,
|
2018-03-02 21:44:14 +01:00
|
|
|
name_changes_disabled: settings_account.update_name_change_display,
|
2017-07-18 02:58:13 +02:00
|
|
|
notifications_stream_id: noop,
|
2020-01-08 01:49:44 +01:00
|
|
|
private_message_policy: noop,
|
2018-02-18 09:34:54 +01:00
|
|
|
send_welcome_emails: noop,
|
2019-01-14 14:04:08 +01:00
|
|
|
message_content_allowed_in_email_notifications: noop,
|
2017-10-20 16:55:04 +02:00
|
|
|
signup_notifications_stream_id: noop,
|
2018-07-27 23:26:29 +02:00
|
|
|
emails_restricted_to_domains: noop,
|
2020-04-08 00:23:15 +02:00
|
|
|
video_chat_provider: compose.update_video_chat_button_display,
|
2017-07-18 02:58:13 +02:00
|
|
|
waiting_period_threshold: noop,
|
|
|
|
};
|
2020-02-09 04:29:30 +01:00
|
|
|
if (event.op === 'update' && Object.prototype.hasOwnProperty.call(realm_settings, event.property)) {
|
2017-07-18 02:58:13 +02:00
|
|
|
page_params['realm_' + event.property] = event.value;
|
|
|
|
realm_settings[event.property]();
|
2018-03-25 15:35:10 +02:00
|
|
|
settings_org.sync_realm_settings(event.property);
|
2019-05-06 16:34:31 +02:00
|
|
|
if (event.property === 'create_stream_policy') {
|
2020-03-26 22:14:57 +01:00
|
|
|
// TODO: Add waiting_period_threshold logic here.
|
|
|
|
page_params.can_create_streams = page_params.is_admin ||
|
|
|
|
page_params.realm_create_stream_policy === 1;
|
2019-04-08 19:23:00 +02:00
|
|
|
} else if (event.property === 'invite_to_stream_policy') {
|
2020-03-26 22:14:57 +01:00
|
|
|
// TODO: Add waiting_period_threshold logic here.
|
|
|
|
page_params.can_invite_to_stream = page_params.is_admin ||
|
|
|
|
page_params.realm_invite_to_stream_policy === 1;
|
2017-05-31 08:53:09 +02:00
|
|
|
}
|
2018-03-20 18:30:25 +01:00
|
|
|
|
|
|
|
if (event.property === 'name' && window.electron_bridge !== undefined) {
|
|
|
|
window.electron_bridge.send_event('realm_name', event.value);
|
|
|
|
}
|
2017-05-31 08:53:09 +02:00
|
|
|
} else if (event.op === 'update_dict' && event.property === 'default') {
|
2020-02-06 04:23:20 +01:00
|
|
|
for (const [key, value] of Object.entries(event.data)) {
|
2017-05-31 08:53:09 +02:00
|
|
|
page_params['realm_' + key] = value;
|
2017-08-20 03:08:53 +02:00
|
|
|
if (key === 'allow_message_editing') {
|
2018-03-05 18:28:37 +01:00
|
|
|
message_edit.update_message_topic_editing_pencil();
|
2017-08-20 03:08:53 +02:00
|
|
|
}
|
2020-02-09 04:29:30 +01:00
|
|
|
if (Object.prototype.hasOwnProperty.call(realm_settings, key)) {
|
2018-03-25 15:35:10 +02:00
|
|
|
settings_org.sync_realm_settings(key);
|
|
|
|
}
|
2020-02-06 04:23:20 +01:00
|
|
|
}
|
2017-05-31 08:53:09 +02:00
|
|
|
if (event.data.authentication_methods !== undefined) {
|
|
|
|
settings_org.populate_auth_methods(event.data.authentication_methods);
|
|
|
|
}
|
|
|
|
} else if (event.op === 'update_dict' && event.property === 'icon') {
|
|
|
|
page_params.realm_icon_url = event.data.icon_url;
|
|
|
|
page_params.realm_icon_source = event.data.icon_source;
|
|
|
|
realm_icon.rerender();
|
2018-03-20 18:28:48 +01:00
|
|
|
|
2019-11-02 00:06:25 +01:00
|
|
|
const electron_bridge = window.electron_bridge;
|
2018-03-20 18:28:48 +01:00
|
|
|
if (electron_bridge !== undefined) {
|
|
|
|
electron_bridge.send_event('realm_icon_url', event.data.icon_url);
|
|
|
|
}
|
2018-08-16 01:26:55 +02:00
|
|
|
} else if (event.op === 'update_dict' && event.property === 'logo') {
|
|
|
|
page_params.realm_logo_url = event.data.logo_url;
|
|
|
|
page_params.realm_logo_source = event.data.logo_source;
|
|
|
|
realm_logo.rerender();
|
2019-01-27 08:25:10 +01:00
|
|
|
} else if (event.op === 'update_dict' && event.property === 'night_logo') {
|
|
|
|
page_params.realm_night_logo_url = event.data.night_logo_url;
|
|
|
|
page_params.realm_night_logo_source = event.data.night_logo_source;
|
|
|
|
realm_logo.rerender();
|
2018-01-30 14:58:50 +01:00
|
|
|
} else if (event.op === 'deactivated') {
|
|
|
|
window.location.href = "/accounts/deactivated/";
|
2017-05-31 08:53:09 +02:00
|
|
|
}
|
|
|
|
|
2020-03-26 08:15:26 +01:00
|
|
|
if (page_params.is_admin) {
|
|
|
|
// Update the UI notice about the user's profile being
|
|
|
|
// incomplete, as we might have filled in the missing field(s).
|
|
|
|
panels.check_profile_incomplete();
|
|
|
|
}
|
2017-05-31 08:53:09 +02:00
|
|
|
break;
|
2019-10-25 23:55:37 +02:00
|
|
|
}
|
2017-05-31 08:53:09 +02:00
|
|
|
|
|
|
|
case 'realm_bot':
|
|
|
|
if (event.op === 'add') {
|
|
|
|
bot_data.add(event.bot);
|
|
|
|
} else if (event.op === 'remove') {
|
2018-01-22 18:36:53 +01:00
|
|
|
bot_data.deactivate(event.bot.user_id);
|
2017-05-31 08:53:09 +02:00
|
|
|
event.bot.is_active = false;
|
2018-03-08 16:28:37 +01:00
|
|
|
} else if (event.op === 'delete') {
|
2020-05-28 22:29:52 +02:00
|
|
|
blueslip.info("ignoring bot deletion for live UI update");
|
|
|
|
break;
|
2017-05-31 08:53:09 +02:00
|
|
|
} else if (event.op === 'update') {
|
2018-01-22 18:36:53 +01:00
|
|
|
bot_data.update(event.bot.user_id, event.bot);
|
2017-05-31 08:53:09 +02:00
|
|
|
}
|
2020-05-20 00:32:34 +02:00
|
|
|
settings_users.update_bot_data(event.bot.user_id);
|
2017-05-31 08:53:09 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
case 'realm_emoji':
|
|
|
|
// Update `page_params.realm_emoji` so that settings page
|
|
|
|
// can display it properly when reopened without refresh.
|
|
|
|
page_params.realm_emoji = event.realm_emoji;
|
|
|
|
emoji.update_emojis(event.realm_emoji);
|
|
|
|
settings_emoji.populate_emoji(event.realm_emoji);
|
2017-07-19 00:28:56 +02:00
|
|
|
emoji_picker.generate_emoji_picker_data(emoji.active_realm_emojis);
|
2018-12-15 13:13:06 +01:00
|
|
|
composebox_typeahead.update_emoji_data();
|
2017-05-31 08:53:09 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
case 'realm_filters':
|
|
|
|
page_params.realm_filters = event.realm_filters;
|
2020-02-17 14:43:59 +01:00
|
|
|
markdown.update_realm_filter_rules(page_params.realm_filters);
|
2018-12-17 21:28:25 +01:00
|
|
|
settings_linkifiers.populate_filters(page_params.realm_filters);
|
2017-05-31 08:53:09 +02:00
|
|
|
break;
|
|
|
|
|
2019-10-25 23:55:37 +02:00
|
|
|
case 'realm_domains': {
|
2019-11-02 00:06:25 +01:00
|
|
|
let i;
|
2017-05-31 08:53:09 +02:00
|
|
|
if (event.op === 'add') {
|
|
|
|
page_params.realm_domains.push(event.realm_domain);
|
|
|
|
} else if (event.op === 'change') {
|
|
|
|
for (i = 0; i < page_params.realm_domains.length; i += 1) {
|
|
|
|
if (page_params.realm_domains[i].domain === event.realm_domain.domain) {
|
|
|
|
page_params.realm_domains[i].allow_subdomains =
|
|
|
|
event.realm_domain.allow_subdomains;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else if (event.op === 'remove') {
|
|
|
|
for (i = 0; i < page_params.realm_domains.length; i += 1) {
|
|
|
|
if (page_params.realm_domains[i].domain === event.domain) {
|
|
|
|
page_params.realm_domains.splice(i, 1);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
settings_org.populate_realm_domains(page_params.realm_domains);
|
|
|
|
break;
|
2019-10-25 23:55:37 +02:00
|
|
|
}
|
2017-05-31 08:53:09 +02:00
|
|
|
|
|
|
|
case 'realm_user':
|
|
|
|
if (event.op === 'add') {
|
2020-05-26 22:34:15 +02:00
|
|
|
people.add_active_user(event.person);
|
2017-05-31 08:53:09 +02:00
|
|
|
} else if (event.op === 'remove') {
|
|
|
|
people.deactivate(event.person);
|
2018-08-04 19:44:31 +02:00
|
|
|
stream_events.remove_deactivated_user_from_all_streams(event.person.user_id);
|
2017-05-31 08:53:09 +02:00
|
|
|
} else if (event.op === 'update') {
|
|
|
|
user_events.update_person(event.person);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 'stream':
|
|
|
|
if (event.op === 'update') {
|
|
|
|
// Legacy: Stream properties are still managed by subs.js on the client side.
|
|
|
|
stream_events.update_property(
|
|
|
|
event.stream_id,
|
|
|
|
event.property,
|
2019-02-05 16:39:46 +01:00
|
|
|
event.value,
|
2019-05-07 08:21:21 +02:00
|
|
|
{
|
|
|
|
rendered_description: event.rendered_description,
|
2019-05-02 19:43:27 +02:00
|
|
|
history_public_to_subscribers: event.history_public_to_subscribers,
|
2019-05-07 08:21:21 +02:00
|
|
|
});
|
2017-05-31 08:53:09 +02:00
|
|
|
settings_streams.update_default_streams_table();
|
|
|
|
} else if (event.op === 'create') {
|
|
|
|
stream_data.create_streams(event.streams);
|
js: Automatically convert _.each to for…of.
This commit was automatically generated by the following script,
followed by lint --fix and a few small manual lint-related cleanups.
import * as babelParser from "recast/parsers/babel";
import * as recast from "recast";
import * as tsParser from "recast/parsers/typescript";
import { builders as b, namedTypes as n } from "ast-types";
import { Context } from "ast-types/lib/path-visitor";
import K from "ast-types/gen/kinds";
import { NodePath } from "ast-types/lib/node-path";
import assert from "assert";
import fs from "fs";
import path from "path";
import process from "process";
const checkExpression = (node: n.Node): node is K.ExpressionKind =>
n.Expression.check(node);
const checkStatement = (node: n.Node): node is K.StatementKind =>
n.Statement.check(node);
for (const file of process.argv.slice(2)) {
console.log("Parsing", file);
const ast = recast.parse(fs.readFileSync(file, { encoding: "utf8" }), {
parser: path.extname(file) === ".ts" ? tsParser : babelParser,
});
let changed = false;
let inLoop = false;
let replaceReturn = false;
const visitLoop = (...args: string[]) =>
function(this: Context, path: NodePath) {
for (const arg of args) {
this.visit(path.get(arg));
}
const old = { inLoop };
inLoop = true;
this.visit(path.get("body"));
inLoop = old.inLoop;
return false;
};
recast.visit(ast, {
visitDoWhileStatement: visitLoop("test"),
visitExpressionStatement(path) {
const { expression, comments } = path.node;
let valueOnly;
if (
n.CallExpression.check(expression) &&
n.MemberExpression.check(expression.callee) &&
!expression.callee.computed &&
n.Identifier.check(expression.callee.object) &&
expression.callee.object.name === "_" &&
n.Identifier.check(expression.callee.property) &&
["each", "forEach"].includes(expression.callee.property.name) &&
[2, 3].includes(expression.arguments.length) &&
checkExpression(expression.arguments[0]) &&
(n.FunctionExpression.check(expression.arguments[1]) ||
n.ArrowFunctionExpression.check(expression.arguments[1])) &&
[1, 2].includes(expression.arguments[1].params.length) &&
n.Identifier.check(expression.arguments[1].params[0]) &&
((valueOnly = expression.arguments[1].params[1] === undefined) ||
n.Identifier.check(expression.arguments[1].params[1])) &&
(expression.arguments[2] === undefined ||
n.ThisExpression.check(expression.arguments[2]))
) {
const old = { inLoop, replaceReturn };
inLoop = false;
replaceReturn = true;
this.visit(
path
.get("expression")
.get("arguments")
.get(1)
.get("body")
);
inLoop = old.inLoop;
replaceReturn = old.replaceReturn;
const [right, { body, params }] = expression.arguments;
const loop = b.forOfStatement(
b.variableDeclaration("let", [
b.variableDeclarator(
valueOnly ? params[0] : b.arrayPattern([params[1], params[0]])
),
]),
valueOnly
? right
: b.callExpression(
b.memberExpression(right, b.identifier("entries")),
[]
),
checkStatement(body) ? body : b.expressionStatement(body)
);
loop.comments = comments;
path.replace(loop);
changed = true;
}
this.traverse(path);
},
visitForStatement: visitLoop("init", "test", "update"),
visitForInStatement: visitLoop("left", "right"),
visitForOfStatement: visitLoop("left", "right"),
visitFunction(path) {
this.visit(path.get("params"));
const old = { replaceReturn };
replaceReturn = false;
this.visit(path.get("body"));
replaceReturn = old.replaceReturn;
return false;
},
visitReturnStatement(path) {
if (replaceReturn) {
assert(!inLoop); // could use labeled continue if this ever fires
const { argument, comments } = path.node;
if (argument === null) {
const s = b.continueStatement();
s.comments = comments;
path.replace(s);
} else {
const s = b.expressionStatement(argument);
s.comments = comments;
path.replace(s, b.continueStatement());
}
return false;
}
this.traverse(path);
},
visitWhileStatement: visitLoop("test"),
});
if (changed) {
console.log("Writing", file);
fs.writeFileSync(file, recast.print(ast).code, { encoding: "utf8" });
}
}
Signed-off-by: Anders Kaseorg <anders@zulipchat.com>
2020-02-06 06:19:47 +01:00
|
|
|
|
|
|
|
for (const stream of event.streams) {
|
2019-11-02 00:06:25 +01:00
|
|
|
const sub = stream_data.get_sub_by_id(stream.stream_id);
|
2018-02-16 07:19:18 +01:00
|
|
|
stream_data.update_calculated_fields(sub);
|
2020-02-26 00:13:44 +01:00
|
|
|
if (overlays.streams_open()) {
|
|
|
|
subs.add_sub_to_table(sub);
|
|
|
|
}
|
js: Automatically convert _.each to for…of.
This commit was automatically generated by the following script,
followed by lint --fix and a few small manual lint-related cleanups.
import * as babelParser from "recast/parsers/babel";
import * as recast from "recast";
import * as tsParser from "recast/parsers/typescript";
import { builders as b, namedTypes as n } from "ast-types";
import { Context } from "ast-types/lib/path-visitor";
import K from "ast-types/gen/kinds";
import { NodePath } from "ast-types/lib/node-path";
import assert from "assert";
import fs from "fs";
import path from "path";
import process from "process";
const checkExpression = (node: n.Node): node is K.ExpressionKind =>
n.Expression.check(node);
const checkStatement = (node: n.Node): node is K.StatementKind =>
n.Statement.check(node);
for (const file of process.argv.slice(2)) {
console.log("Parsing", file);
const ast = recast.parse(fs.readFileSync(file, { encoding: "utf8" }), {
parser: path.extname(file) === ".ts" ? tsParser : babelParser,
});
let changed = false;
let inLoop = false;
let replaceReturn = false;
const visitLoop = (...args: string[]) =>
function(this: Context, path: NodePath) {
for (const arg of args) {
this.visit(path.get(arg));
}
const old = { inLoop };
inLoop = true;
this.visit(path.get("body"));
inLoop = old.inLoop;
return false;
};
recast.visit(ast, {
visitDoWhileStatement: visitLoop("test"),
visitExpressionStatement(path) {
const { expression, comments } = path.node;
let valueOnly;
if (
n.CallExpression.check(expression) &&
n.MemberExpression.check(expression.callee) &&
!expression.callee.computed &&
n.Identifier.check(expression.callee.object) &&
expression.callee.object.name === "_" &&
n.Identifier.check(expression.callee.property) &&
["each", "forEach"].includes(expression.callee.property.name) &&
[2, 3].includes(expression.arguments.length) &&
checkExpression(expression.arguments[0]) &&
(n.FunctionExpression.check(expression.arguments[1]) ||
n.ArrowFunctionExpression.check(expression.arguments[1])) &&
[1, 2].includes(expression.arguments[1].params.length) &&
n.Identifier.check(expression.arguments[1].params[0]) &&
((valueOnly = expression.arguments[1].params[1] === undefined) ||
n.Identifier.check(expression.arguments[1].params[1])) &&
(expression.arguments[2] === undefined ||
n.ThisExpression.check(expression.arguments[2]))
) {
const old = { inLoop, replaceReturn };
inLoop = false;
replaceReturn = true;
this.visit(
path
.get("expression")
.get("arguments")
.get(1)
.get("body")
);
inLoop = old.inLoop;
replaceReturn = old.replaceReturn;
const [right, { body, params }] = expression.arguments;
const loop = b.forOfStatement(
b.variableDeclaration("let", [
b.variableDeclarator(
valueOnly ? params[0] : b.arrayPattern([params[1], params[0]])
),
]),
valueOnly
? right
: b.callExpression(
b.memberExpression(right, b.identifier("entries")),
[]
),
checkStatement(body) ? body : b.expressionStatement(body)
);
loop.comments = comments;
path.replace(loop);
changed = true;
}
this.traverse(path);
},
visitForStatement: visitLoop("init", "test", "update"),
visitForInStatement: visitLoop("left", "right"),
visitForOfStatement: visitLoop("left", "right"),
visitFunction(path) {
this.visit(path.get("params"));
const old = { replaceReturn };
replaceReturn = false;
this.visit(path.get("body"));
replaceReturn = old.replaceReturn;
return false;
},
visitReturnStatement(path) {
if (replaceReturn) {
assert(!inLoop); // could use labeled continue if this ever fires
const { argument, comments } = path.node;
if (argument === null) {
const s = b.continueStatement();
s.comments = comments;
path.replace(s);
} else {
const s = b.expressionStatement(argument);
s.comments = comments;
path.replace(s, b.continueStatement());
}
return false;
}
this.traverse(path);
},
visitWhileStatement: visitLoop("test"),
});
if (changed) {
console.log("Writing", file);
fs.writeFileSync(file, recast.print(ast).code, { encoding: "utf8" });
}
}
Signed-off-by: Anders Kaseorg <anders@zulipchat.com>
2020-02-06 06:19:47 +01:00
|
|
|
}
|
2017-05-31 08:53:09 +02:00
|
|
|
} else if (event.op === 'delete') {
|
js: Automatically convert _.each to for…of.
This commit was automatically generated by the following script,
followed by lint --fix and a few small manual lint-related cleanups.
import * as babelParser from "recast/parsers/babel";
import * as recast from "recast";
import * as tsParser from "recast/parsers/typescript";
import { builders as b, namedTypes as n } from "ast-types";
import { Context } from "ast-types/lib/path-visitor";
import K from "ast-types/gen/kinds";
import { NodePath } from "ast-types/lib/node-path";
import assert from "assert";
import fs from "fs";
import path from "path";
import process from "process";
const checkExpression = (node: n.Node): node is K.ExpressionKind =>
n.Expression.check(node);
const checkStatement = (node: n.Node): node is K.StatementKind =>
n.Statement.check(node);
for (const file of process.argv.slice(2)) {
console.log("Parsing", file);
const ast = recast.parse(fs.readFileSync(file, { encoding: "utf8" }), {
parser: path.extname(file) === ".ts" ? tsParser : babelParser,
});
let changed = false;
let inLoop = false;
let replaceReturn = false;
const visitLoop = (...args: string[]) =>
function(this: Context, path: NodePath) {
for (const arg of args) {
this.visit(path.get(arg));
}
const old = { inLoop };
inLoop = true;
this.visit(path.get("body"));
inLoop = old.inLoop;
return false;
};
recast.visit(ast, {
visitDoWhileStatement: visitLoop("test"),
visitExpressionStatement(path) {
const { expression, comments } = path.node;
let valueOnly;
if (
n.CallExpression.check(expression) &&
n.MemberExpression.check(expression.callee) &&
!expression.callee.computed &&
n.Identifier.check(expression.callee.object) &&
expression.callee.object.name === "_" &&
n.Identifier.check(expression.callee.property) &&
["each", "forEach"].includes(expression.callee.property.name) &&
[2, 3].includes(expression.arguments.length) &&
checkExpression(expression.arguments[0]) &&
(n.FunctionExpression.check(expression.arguments[1]) ||
n.ArrowFunctionExpression.check(expression.arguments[1])) &&
[1, 2].includes(expression.arguments[1].params.length) &&
n.Identifier.check(expression.arguments[1].params[0]) &&
((valueOnly = expression.arguments[1].params[1] === undefined) ||
n.Identifier.check(expression.arguments[1].params[1])) &&
(expression.arguments[2] === undefined ||
n.ThisExpression.check(expression.arguments[2]))
) {
const old = { inLoop, replaceReturn };
inLoop = false;
replaceReturn = true;
this.visit(
path
.get("expression")
.get("arguments")
.get(1)
.get("body")
);
inLoop = old.inLoop;
replaceReturn = old.replaceReturn;
const [right, { body, params }] = expression.arguments;
const loop = b.forOfStatement(
b.variableDeclaration("let", [
b.variableDeclarator(
valueOnly ? params[0] : b.arrayPattern([params[1], params[0]])
),
]),
valueOnly
? right
: b.callExpression(
b.memberExpression(right, b.identifier("entries")),
[]
),
checkStatement(body) ? body : b.expressionStatement(body)
);
loop.comments = comments;
path.replace(loop);
changed = true;
}
this.traverse(path);
},
visitForStatement: visitLoop("init", "test", "update"),
visitForInStatement: visitLoop("left", "right"),
visitForOfStatement: visitLoop("left", "right"),
visitFunction(path) {
this.visit(path.get("params"));
const old = { replaceReturn };
replaceReturn = false;
this.visit(path.get("body"));
replaceReturn = old.replaceReturn;
return false;
},
visitReturnStatement(path) {
if (replaceReturn) {
assert(!inLoop); // could use labeled continue if this ever fires
const { argument, comments } = path.node;
if (argument === null) {
const s = b.continueStatement();
s.comments = comments;
path.replace(s);
} else {
const s = b.expressionStatement(argument);
s.comments = comments;
path.replace(s, b.continueStatement());
}
return false;
}
this.traverse(path);
},
visitWhileStatement: visitLoop("test"),
});
if (changed) {
console.log("Writing", file);
fs.writeFileSync(file, recast.print(ast).code, { encoding: "utf8" });
}
}
Signed-off-by: Anders Kaseorg <anders@zulipchat.com>
2020-02-06 06:19:47 +01:00
|
|
|
for (const stream of event.streams) {
|
2019-11-02 00:06:25 +01:00
|
|
|
const was_subscribed = stream_data.get_sub_by_id(stream.stream_id).subscribed;
|
2017-08-22 23:19:18 +02:00
|
|
|
subs.remove_stream(stream.stream_id);
|
2018-08-07 15:41:00 +02:00
|
|
|
stream_data.delete_sub(stream.stream_id);
|
2017-08-22 23:19:18 +02:00
|
|
|
if (was_subscribed) {
|
2017-05-31 08:53:09 +02:00
|
|
|
stream_list.remove_sidebar_row(stream.stream_id);
|
|
|
|
}
|
2020-03-22 14:38:19 +01:00
|
|
|
settings_streams.update_default_streams_table();
|
2017-05-31 08:53:09 +02:00
|
|
|
stream_data.remove_default_stream(stream.stream_id);
|
2017-06-10 07:03:53 +02:00
|
|
|
if (page_params.realm_notifications_stream_id === stream.stream_id) {
|
|
|
|
page_params.realm_notifications_stream_id = -1;
|
2020-05-16 07:08:35 +02:00
|
|
|
settings_org.sync_realm_settings('notifications_stream_id');
|
2017-06-10 07:03:53 +02:00
|
|
|
}
|
2017-10-20 16:55:04 +02:00
|
|
|
if (page_params.realm_signup_notifications_stream_id === stream.stream_id) {
|
|
|
|
page_params.realm_signup_notifications_stream_id = -1;
|
2020-05-16 07:08:35 +02:00
|
|
|
settings_org.sync_realm_settings('signup_notifications_stream_id');
|
2017-10-20 16:55:04 +02:00
|
|
|
}
|
js: Automatically convert _.each to for…of.
This commit was automatically generated by the following script,
followed by lint --fix and a few small manual lint-related cleanups.
import * as babelParser from "recast/parsers/babel";
import * as recast from "recast";
import * as tsParser from "recast/parsers/typescript";
import { builders as b, namedTypes as n } from "ast-types";
import { Context } from "ast-types/lib/path-visitor";
import K from "ast-types/gen/kinds";
import { NodePath } from "ast-types/lib/node-path";
import assert from "assert";
import fs from "fs";
import path from "path";
import process from "process";
const checkExpression = (node: n.Node): node is K.ExpressionKind =>
n.Expression.check(node);
const checkStatement = (node: n.Node): node is K.StatementKind =>
n.Statement.check(node);
for (const file of process.argv.slice(2)) {
console.log("Parsing", file);
const ast = recast.parse(fs.readFileSync(file, { encoding: "utf8" }), {
parser: path.extname(file) === ".ts" ? tsParser : babelParser,
});
let changed = false;
let inLoop = false;
let replaceReturn = false;
const visitLoop = (...args: string[]) =>
function(this: Context, path: NodePath) {
for (const arg of args) {
this.visit(path.get(arg));
}
const old = { inLoop };
inLoop = true;
this.visit(path.get("body"));
inLoop = old.inLoop;
return false;
};
recast.visit(ast, {
visitDoWhileStatement: visitLoop("test"),
visitExpressionStatement(path) {
const { expression, comments } = path.node;
let valueOnly;
if (
n.CallExpression.check(expression) &&
n.MemberExpression.check(expression.callee) &&
!expression.callee.computed &&
n.Identifier.check(expression.callee.object) &&
expression.callee.object.name === "_" &&
n.Identifier.check(expression.callee.property) &&
["each", "forEach"].includes(expression.callee.property.name) &&
[2, 3].includes(expression.arguments.length) &&
checkExpression(expression.arguments[0]) &&
(n.FunctionExpression.check(expression.arguments[1]) ||
n.ArrowFunctionExpression.check(expression.arguments[1])) &&
[1, 2].includes(expression.arguments[1].params.length) &&
n.Identifier.check(expression.arguments[1].params[0]) &&
((valueOnly = expression.arguments[1].params[1] === undefined) ||
n.Identifier.check(expression.arguments[1].params[1])) &&
(expression.arguments[2] === undefined ||
n.ThisExpression.check(expression.arguments[2]))
) {
const old = { inLoop, replaceReturn };
inLoop = false;
replaceReturn = true;
this.visit(
path
.get("expression")
.get("arguments")
.get(1)
.get("body")
);
inLoop = old.inLoop;
replaceReturn = old.replaceReturn;
const [right, { body, params }] = expression.arguments;
const loop = b.forOfStatement(
b.variableDeclaration("let", [
b.variableDeclarator(
valueOnly ? params[0] : b.arrayPattern([params[1], params[0]])
),
]),
valueOnly
? right
: b.callExpression(
b.memberExpression(right, b.identifier("entries")),
[]
),
checkStatement(body) ? body : b.expressionStatement(body)
);
loop.comments = comments;
path.replace(loop);
changed = true;
}
this.traverse(path);
},
visitForStatement: visitLoop("init", "test", "update"),
visitForInStatement: visitLoop("left", "right"),
visitForOfStatement: visitLoop("left", "right"),
visitFunction(path) {
this.visit(path.get("params"));
const old = { replaceReturn };
replaceReturn = false;
this.visit(path.get("body"));
replaceReturn = old.replaceReturn;
return false;
},
visitReturnStatement(path) {
if (replaceReturn) {
assert(!inLoop); // could use labeled continue if this ever fires
const { argument, comments } = path.node;
if (argument === null) {
const s = b.continueStatement();
s.comments = comments;
path.replace(s);
} else {
const s = b.expressionStatement(argument);
s.comments = comments;
path.replace(s, b.continueStatement());
}
return false;
}
this.traverse(path);
},
visitWhileStatement: visitLoop("test"),
});
if (changed) {
console.log("Writing", file);
fs.writeFileSync(file, recast.print(ast).code, { encoding: "utf8" });
}
}
Signed-off-by: Anders Kaseorg <anders@zulipchat.com>
2020-02-06 06:19:47 +01:00
|
|
|
}
|
2017-05-31 08:53:09 +02:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2019-10-25 23:55:37 +02:00
|
|
|
case 'submessage': {
|
2018-05-30 22:29:56 +02:00
|
|
|
// The fields in the event don't quite exactly
|
|
|
|
// match the layout of a submessage, since there's
|
|
|
|
// an event id. We also want to be explicit here.
|
2019-11-02 00:06:25 +01:00
|
|
|
const submsg = {
|
2018-05-30 22:29:56 +02:00
|
|
|
id: event.submessage_id,
|
2018-02-12 15:12:40 +01:00
|
|
|
sender_id: event.sender_id,
|
|
|
|
msg_type: event.msg_type,
|
|
|
|
message_id: event.message_id,
|
2018-05-30 21:12:16 +02:00
|
|
|
content: event.content,
|
2018-05-30 22:29:56 +02:00
|
|
|
};
|
|
|
|
submessage.handle_event(submsg);
|
2018-02-12 15:12:40 +01:00
|
|
|
break;
|
2019-10-25 23:55:37 +02:00
|
|
|
}
|
2018-02-12 15:12:40 +01:00
|
|
|
|
2017-05-31 08:53:09 +02:00
|
|
|
case 'subscription':
|
|
|
|
if (event.op === 'add') {
|
js: Automatically convert _.each to for…of.
This commit was automatically generated by the following script,
followed by lint --fix and a few small manual lint-related cleanups.
import * as babelParser from "recast/parsers/babel";
import * as recast from "recast";
import * as tsParser from "recast/parsers/typescript";
import { builders as b, namedTypes as n } from "ast-types";
import { Context } from "ast-types/lib/path-visitor";
import K from "ast-types/gen/kinds";
import { NodePath } from "ast-types/lib/node-path";
import assert from "assert";
import fs from "fs";
import path from "path";
import process from "process";
const checkExpression = (node: n.Node): node is K.ExpressionKind =>
n.Expression.check(node);
const checkStatement = (node: n.Node): node is K.StatementKind =>
n.Statement.check(node);
for (const file of process.argv.slice(2)) {
console.log("Parsing", file);
const ast = recast.parse(fs.readFileSync(file, { encoding: "utf8" }), {
parser: path.extname(file) === ".ts" ? tsParser : babelParser,
});
let changed = false;
let inLoop = false;
let replaceReturn = false;
const visitLoop = (...args: string[]) =>
function(this: Context, path: NodePath) {
for (const arg of args) {
this.visit(path.get(arg));
}
const old = { inLoop };
inLoop = true;
this.visit(path.get("body"));
inLoop = old.inLoop;
return false;
};
recast.visit(ast, {
visitDoWhileStatement: visitLoop("test"),
visitExpressionStatement(path) {
const { expression, comments } = path.node;
let valueOnly;
if (
n.CallExpression.check(expression) &&
n.MemberExpression.check(expression.callee) &&
!expression.callee.computed &&
n.Identifier.check(expression.callee.object) &&
expression.callee.object.name === "_" &&
n.Identifier.check(expression.callee.property) &&
["each", "forEach"].includes(expression.callee.property.name) &&
[2, 3].includes(expression.arguments.length) &&
checkExpression(expression.arguments[0]) &&
(n.FunctionExpression.check(expression.arguments[1]) ||
n.ArrowFunctionExpression.check(expression.arguments[1])) &&
[1, 2].includes(expression.arguments[1].params.length) &&
n.Identifier.check(expression.arguments[1].params[0]) &&
((valueOnly = expression.arguments[1].params[1] === undefined) ||
n.Identifier.check(expression.arguments[1].params[1])) &&
(expression.arguments[2] === undefined ||
n.ThisExpression.check(expression.arguments[2]))
) {
const old = { inLoop, replaceReturn };
inLoop = false;
replaceReturn = true;
this.visit(
path
.get("expression")
.get("arguments")
.get(1)
.get("body")
);
inLoop = old.inLoop;
replaceReturn = old.replaceReturn;
const [right, { body, params }] = expression.arguments;
const loop = b.forOfStatement(
b.variableDeclaration("let", [
b.variableDeclarator(
valueOnly ? params[0] : b.arrayPattern([params[1], params[0]])
),
]),
valueOnly
? right
: b.callExpression(
b.memberExpression(right, b.identifier("entries")),
[]
),
checkStatement(body) ? body : b.expressionStatement(body)
);
loop.comments = comments;
path.replace(loop);
changed = true;
}
this.traverse(path);
},
visitForStatement: visitLoop("init", "test", "update"),
visitForInStatement: visitLoop("left", "right"),
visitForOfStatement: visitLoop("left", "right"),
visitFunction(path) {
this.visit(path.get("params"));
const old = { replaceReturn };
replaceReturn = false;
this.visit(path.get("body"));
replaceReturn = old.replaceReturn;
return false;
},
visitReturnStatement(path) {
if (replaceReturn) {
assert(!inLoop); // could use labeled continue if this ever fires
const { argument, comments } = path.node;
if (argument === null) {
const s = b.continueStatement();
s.comments = comments;
path.replace(s);
} else {
const s = b.expressionStatement(argument);
s.comments = comments;
path.replace(s, b.continueStatement());
}
return false;
}
this.traverse(path);
},
visitWhileStatement: visitLoop("test"),
});
if (changed) {
console.log("Writing", file);
fs.writeFileSync(file, recast.print(ast).code, { encoding: "utf8" });
}
}
Signed-off-by: Anders Kaseorg <anders@zulipchat.com>
2020-02-06 06:19:47 +01:00
|
|
|
for (const rec of event.subscriptions) {
|
2019-11-02 00:06:25 +01:00
|
|
|
const sub = stream_data.get_sub_by_id(rec.stream_id);
|
2017-05-31 08:53:09 +02:00
|
|
|
if (sub) {
|
2018-04-05 19:58:27 +02:00
|
|
|
stream_data.update_stream_email_address(sub, rec.email_address);
|
2018-11-10 01:57:10 +01:00
|
|
|
stream_events.mark_subscribed(sub, rec.subscribers, rec.color);
|
2017-05-31 08:53:09 +02:00
|
|
|
} else {
|
2017-08-16 20:59:49 +02:00
|
|
|
blueslip.error('Subscribing to unknown stream with ID ' + rec.stream_id);
|
2017-05-31 08:53:09 +02:00
|
|
|
}
|
js: Automatically convert _.each to for…of.
This commit was automatically generated by the following script,
followed by lint --fix and a few small manual lint-related cleanups.
import * as babelParser from "recast/parsers/babel";
import * as recast from "recast";
import * as tsParser from "recast/parsers/typescript";
import { builders as b, namedTypes as n } from "ast-types";
import { Context } from "ast-types/lib/path-visitor";
import K from "ast-types/gen/kinds";
import { NodePath } from "ast-types/lib/node-path";
import assert from "assert";
import fs from "fs";
import path from "path";
import process from "process";
const checkExpression = (node: n.Node): node is K.ExpressionKind =>
n.Expression.check(node);
const checkStatement = (node: n.Node): node is K.StatementKind =>
n.Statement.check(node);
for (const file of process.argv.slice(2)) {
console.log("Parsing", file);
const ast = recast.parse(fs.readFileSync(file, { encoding: "utf8" }), {
parser: path.extname(file) === ".ts" ? tsParser : babelParser,
});
let changed = false;
let inLoop = false;
let replaceReturn = false;
const visitLoop = (...args: string[]) =>
function(this: Context, path: NodePath) {
for (const arg of args) {
this.visit(path.get(arg));
}
const old = { inLoop };
inLoop = true;
this.visit(path.get("body"));
inLoop = old.inLoop;
return false;
};
recast.visit(ast, {
visitDoWhileStatement: visitLoop("test"),
visitExpressionStatement(path) {
const { expression, comments } = path.node;
let valueOnly;
if (
n.CallExpression.check(expression) &&
n.MemberExpression.check(expression.callee) &&
!expression.callee.computed &&
n.Identifier.check(expression.callee.object) &&
expression.callee.object.name === "_" &&
n.Identifier.check(expression.callee.property) &&
["each", "forEach"].includes(expression.callee.property.name) &&
[2, 3].includes(expression.arguments.length) &&
checkExpression(expression.arguments[0]) &&
(n.FunctionExpression.check(expression.arguments[1]) ||
n.ArrowFunctionExpression.check(expression.arguments[1])) &&
[1, 2].includes(expression.arguments[1].params.length) &&
n.Identifier.check(expression.arguments[1].params[0]) &&
((valueOnly = expression.arguments[1].params[1] === undefined) ||
n.Identifier.check(expression.arguments[1].params[1])) &&
(expression.arguments[2] === undefined ||
n.ThisExpression.check(expression.arguments[2]))
) {
const old = { inLoop, replaceReturn };
inLoop = false;
replaceReturn = true;
this.visit(
path
.get("expression")
.get("arguments")
.get(1)
.get("body")
);
inLoop = old.inLoop;
replaceReturn = old.replaceReturn;
const [right, { body, params }] = expression.arguments;
const loop = b.forOfStatement(
b.variableDeclaration("let", [
b.variableDeclarator(
valueOnly ? params[0] : b.arrayPattern([params[1], params[0]])
),
]),
valueOnly
? right
: b.callExpression(
b.memberExpression(right, b.identifier("entries")),
[]
),
checkStatement(body) ? body : b.expressionStatement(body)
);
loop.comments = comments;
path.replace(loop);
changed = true;
}
this.traverse(path);
},
visitForStatement: visitLoop("init", "test", "update"),
visitForInStatement: visitLoop("left", "right"),
visitForOfStatement: visitLoop("left", "right"),
visitFunction(path) {
this.visit(path.get("params"));
const old = { replaceReturn };
replaceReturn = false;
this.visit(path.get("body"));
replaceReturn = old.replaceReturn;
return false;
},
visitReturnStatement(path) {
if (replaceReturn) {
assert(!inLoop); // could use labeled continue if this ever fires
const { argument, comments } = path.node;
if (argument === null) {
const s = b.continueStatement();
s.comments = comments;
path.replace(s);
} else {
const s = b.expressionStatement(argument);
s.comments = comments;
path.replace(s, b.continueStatement());
}
return false;
}
this.traverse(path);
},
visitWhileStatement: visitLoop("test"),
});
if (changed) {
console.log("Writing", file);
fs.writeFileSync(file, recast.print(ast).code, { encoding: "utf8" });
}
}
Signed-off-by: Anders Kaseorg <anders@zulipchat.com>
2020-02-06 06:19:47 +01:00
|
|
|
}
|
2017-05-31 08:53:09 +02:00
|
|
|
} else if (event.op === 'peer_add') {
|
2020-06-12 16:54:01 +02:00
|
|
|
function add_peer(stream_id, user_id) {
|
|
|
|
const sub = stream_data.get_sub_by_id(stream_id);
|
|
|
|
|
|
|
|
if (!sub) {
|
|
|
|
blueslip.warn('Cannot find stream for peer_add: ' + stream_id);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2020-06-20 21:35:41 +02:00
|
|
|
if (!stream_data.add_subscriber(stream_id, user_id)) {
|
2017-05-31 08:53:09 +02:00
|
|
|
blueslip.warn('Cannot process peer_add event');
|
2020-06-12 18:10:58 +02:00
|
|
|
return;
|
2017-05-31 08:53:09 +02:00
|
|
|
}
|
2020-06-12 18:10:58 +02:00
|
|
|
|
2020-06-20 19:58:38 +02:00
|
|
|
subs.rerender_subscriptions_settings(sub);
|
2020-06-12 16:54:01 +02:00
|
|
|
compose_fade.update_faded_users();
|
js: Automatically convert _.each to for…of.
This commit was automatically generated by the following script,
followed by lint --fix and a few small manual lint-related cleanups.
import * as babelParser from "recast/parsers/babel";
import * as recast from "recast";
import * as tsParser from "recast/parsers/typescript";
import { builders as b, namedTypes as n } from "ast-types";
import { Context } from "ast-types/lib/path-visitor";
import K from "ast-types/gen/kinds";
import { NodePath } from "ast-types/lib/node-path";
import assert from "assert";
import fs from "fs";
import path from "path";
import process from "process";
const checkExpression = (node: n.Node): node is K.ExpressionKind =>
n.Expression.check(node);
const checkStatement = (node: n.Node): node is K.StatementKind =>
n.Statement.check(node);
for (const file of process.argv.slice(2)) {
console.log("Parsing", file);
const ast = recast.parse(fs.readFileSync(file, { encoding: "utf8" }), {
parser: path.extname(file) === ".ts" ? tsParser : babelParser,
});
let changed = false;
let inLoop = false;
let replaceReturn = false;
const visitLoop = (...args: string[]) =>
function(this: Context, path: NodePath) {
for (const arg of args) {
this.visit(path.get(arg));
}
const old = { inLoop };
inLoop = true;
this.visit(path.get("body"));
inLoop = old.inLoop;
return false;
};
recast.visit(ast, {
visitDoWhileStatement: visitLoop("test"),
visitExpressionStatement(path) {
const { expression, comments } = path.node;
let valueOnly;
if (
n.CallExpression.check(expression) &&
n.MemberExpression.check(expression.callee) &&
!expression.callee.computed &&
n.Identifier.check(expression.callee.object) &&
expression.callee.object.name === "_" &&
n.Identifier.check(expression.callee.property) &&
["each", "forEach"].includes(expression.callee.property.name) &&
[2, 3].includes(expression.arguments.length) &&
checkExpression(expression.arguments[0]) &&
(n.FunctionExpression.check(expression.arguments[1]) ||
n.ArrowFunctionExpression.check(expression.arguments[1])) &&
[1, 2].includes(expression.arguments[1].params.length) &&
n.Identifier.check(expression.arguments[1].params[0]) &&
((valueOnly = expression.arguments[1].params[1] === undefined) ||
n.Identifier.check(expression.arguments[1].params[1])) &&
(expression.arguments[2] === undefined ||
n.ThisExpression.check(expression.arguments[2]))
) {
const old = { inLoop, replaceReturn };
inLoop = false;
replaceReturn = true;
this.visit(
path
.get("expression")
.get("arguments")
.get(1)
.get("body")
);
inLoop = old.inLoop;
replaceReturn = old.replaceReturn;
const [right, { body, params }] = expression.arguments;
const loop = b.forOfStatement(
b.variableDeclaration("let", [
b.variableDeclarator(
valueOnly ? params[0] : b.arrayPattern([params[1], params[0]])
),
]),
valueOnly
? right
: b.callExpression(
b.memberExpression(right, b.identifier("entries")),
[]
),
checkStatement(body) ? body : b.expressionStatement(body)
);
loop.comments = comments;
path.replace(loop);
changed = true;
}
this.traverse(path);
},
visitForStatement: visitLoop("init", "test", "update"),
visitForInStatement: visitLoop("left", "right"),
visitForOfStatement: visitLoop("left", "right"),
visitFunction(path) {
this.visit(path.get("params"));
const old = { replaceReturn };
replaceReturn = false;
this.visit(path.get("body"));
replaceReturn = old.replaceReturn;
return false;
},
visitReturnStatement(path) {
if (replaceReturn) {
assert(!inLoop); // could use labeled continue if this ever fires
const { argument, comments } = path.node;
if (argument === null) {
const s = b.continueStatement();
s.comments = comments;
path.replace(s);
} else {
const s = b.expressionStatement(argument);
s.comments = comments;
path.replace(s, b.continueStatement());
}
return false;
}
this.traverse(path);
},
visitWhileStatement: visitLoop("test"),
});
if (changed) {
console.log("Writing", file);
fs.writeFileSync(file, recast.print(ast).code, { encoding: "utf8" });
}
}
Signed-off-by: Anders Kaseorg <anders@zulipchat.com>
2020-02-06 06:19:47 +01:00
|
|
|
}
|
2020-06-12 16:54:01 +02:00
|
|
|
add_peer(event.stream_id, event.user_id);
|
2017-05-31 08:53:09 +02:00
|
|
|
} else if (event.op === 'peer_remove') {
|
2020-06-12 16:54:01 +02:00
|
|
|
function remove_peer(stream_id, user_id) {
|
|
|
|
const sub = stream_data.get_sub_by_id(stream_id);
|
|
|
|
|
|
|
|
if (!sub) {
|
|
|
|
blueslip.warn('Cannot find stream for peer_remove: ' + stream_id);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2020-06-20 21:52:31 +02:00
|
|
|
if (!stream_data.remove_subscriber(sub.stream_id, user_id)) {
|
2017-05-31 08:53:09 +02:00
|
|
|
blueslip.warn('Cannot process peer_remove event.');
|
2020-06-12 18:10:58 +02:00
|
|
|
return;
|
2017-05-31 08:53:09 +02:00
|
|
|
}
|
2020-06-12 16:54:01 +02:00
|
|
|
|
2020-06-20 19:58:38 +02:00
|
|
|
subs.rerender_subscriptions_settings(sub);
|
2020-06-12 16:54:01 +02:00
|
|
|
compose_fade.update_faded_users();
|
js: Automatically convert _.each to for…of.
This commit was automatically generated by the following script,
followed by lint --fix and a few small manual lint-related cleanups.
import * as babelParser from "recast/parsers/babel";
import * as recast from "recast";
import * as tsParser from "recast/parsers/typescript";
import { builders as b, namedTypes as n } from "ast-types";
import { Context } from "ast-types/lib/path-visitor";
import K from "ast-types/gen/kinds";
import { NodePath } from "ast-types/lib/node-path";
import assert from "assert";
import fs from "fs";
import path from "path";
import process from "process";
const checkExpression = (node: n.Node): node is K.ExpressionKind =>
n.Expression.check(node);
const checkStatement = (node: n.Node): node is K.StatementKind =>
n.Statement.check(node);
for (const file of process.argv.slice(2)) {
console.log("Parsing", file);
const ast = recast.parse(fs.readFileSync(file, { encoding: "utf8" }), {
parser: path.extname(file) === ".ts" ? tsParser : babelParser,
});
let changed = false;
let inLoop = false;
let replaceReturn = false;
const visitLoop = (...args: string[]) =>
function(this: Context, path: NodePath) {
for (const arg of args) {
this.visit(path.get(arg));
}
const old = { inLoop };
inLoop = true;
this.visit(path.get("body"));
inLoop = old.inLoop;
return false;
};
recast.visit(ast, {
visitDoWhileStatement: visitLoop("test"),
visitExpressionStatement(path) {
const { expression, comments } = path.node;
let valueOnly;
if (
n.CallExpression.check(expression) &&
n.MemberExpression.check(expression.callee) &&
!expression.callee.computed &&
n.Identifier.check(expression.callee.object) &&
expression.callee.object.name === "_" &&
n.Identifier.check(expression.callee.property) &&
["each", "forEach"].includes(expression.callee.property.name) &&
[2, 3].includes(expression.arguments.length) &&
checkExpression(expression.arguments[0]) &&
(n.FunctionExpression.check(expression.arguments[1]) ||
n.ArrowFunctionExpression.check(expression.arguments[1])) &&
[1, 2].includes(expression.arguments[1].params.length) &&
n.Identifier.check(expression.arguments[1].params[0]) &&
((valueOnly = expression.arguments[1].params[1] === undefined) ||
n.Identifier.check(expression.arguments[1].params[1])) &&
(expression.arguments[2] === undefined ||
n.ThisExpression.check(expression.arguments[2]))
) {
const old = { inLoop, replaceReturn };
inLoop = false;
replaceReturn = true;
this.visit(
path
.get("expression")
.get("arguments")
.get(1)
.get("body")
);
inLoop = old.inLoop;
replaceReturn = old.replaceReturn;
const [right, { body, params }] = expression.arguments;
const loop = b.forOfStatement(
b.variableDeclaration("let", [
b.variableDeclarator(
valueOnly ? params[0] : b.arrayPattern([params[1], params[0]])
),
]),
valueOnly
? right
: b.callExpression(
b.memberExpression(right, b.identifier("entries")),
[]
),
checkStatement(body) ? body : b.expressionStatement(body)
);
loop.comments = comments;
path.replace(loop);
changed = true;
}
this.traverse(path);
},
visitForStatement: visitLoop("init", "test", "update"),
visitForInStatement: visitLoop("left", "right"),
visitForOfStatement: visitLoop("left", "right"),
visitFunction(path) {
this.visit(path.get("params"));
const old = { replaceReturn };
replaceReturn = false;
this.visit(path.get("body"));
replaceReturn = old.replaceReturn;
return false;
},
visitReturnStatement(path) {
if (replaceReturn) {
assert(!inLoop); // could use labeled continue if this ever fires
const { argument, comments } = path.node;
if (argument === null) {
const s = b.continueStatement();
s.comments = comments;
path.replace(s);
} else {
const s = b.expressionStatement(argument);
s.comments = comments;
path.replace(s, b.continueStatement());
}
return false;
}
this.traverse(path);
},
visitWhileStatement: visitLoop("test"),
});
if (changed) {
console.log("Writing", file);
fs.writeFileSync(file, recast.print(ast).code, { encoding: "utf8" });
}
}
Signed-off-by: Anders Kaseorg <anders@zulipchat.com>
2020-02-06 06:19:47 +01:00
|
|
|
}
|
2020-06-12 16:54:01 +02:00
|
|
|
remove_peer(event.stream_id, event.user_id);
|
2017-05-31 08:53:09 +02:00
|
|
|
} else if (event.op === 'remove') {
|
js: Automatically convert _.each to for…of.
This commit was automatically generated by the following script,
followed by lint --fix and a few small manual lint-related cleanups.
import * as babelParser from "recast/parsers/babel";
import * as recast from "recast";
import * as tsParser from "recast/parsers/typescript";
import { builders as b, namedTypes as n } from "ast-types";
import { Context } from "ast-types/lib/path-visitor";
import K from "ast-types/gen/kinds";
import { NodePath } from "ast-types/lib/node-path";
import assert from "assert";
import fs from "fs";
import path from "path";
import process from "process";
const checkExpression = (node: n.Node): node is K.ExpressionKind =>
n.Expression.check(node);
const checkStatement = (node: n.Node): node is K.StatementKind =>
n.Statement.check(node);
for (const file of process.argv.slice(2)) {
console.log("Parsing", file);
const ast = recast.parse(fs.readFileSync(file, { encoding: "utf8" }), {
parser: path.extname(file) === ".ts" ? tsParser : babelParser,
});
let changed = false;
let inLoop = false;
let replaceReturn = false;
const visitLoop = (...args: string[]) =>
function(this: Context, path: NodePath) {
for (const arg of args) {
this.visit(path.get(arg));
}
const old = { inLoop };
inLoop = true;
this.visit(path.get("body"));
inLoop = old.inLoop;
return false;
};
recast.visit(ast, {
visitDoWhileStatement: visitLoop("test"),
visitExpressionStatement(path) {
const { expression, comments } = path.node;
let valueOnly;
if (
n.CallExpression.check(expression) &&
n.MemberExpression.check(expression.callee) &&
!expression.callee.computed &&
n.Identifier.check(expression.callee.object) &&
expression.callee.object.name === "_" &&
n.Identifier.check(expression.callee.property) &&
["each", "forEach"].includes(expression.callee.property.name) &&
[2, 3].includes(expression.arguments.length) &&
checkExpression(expression.arguments[0]) &&
(n.FunctionExpression.check(expression.arguments[1]) ||
n.ArrowFunctionExpression.check(expression.arguments[1])) &&
[1, 2].includes(expression.arguments[1].params.length) &&
n.Identifier.check(expression.arguments[1].params[0]) &&
((valueOnly = expression.arguments[1].params[1] === undefined) ||
n.Identifier.check(expression.arguments[1].params[1])) &&
(expression.arguments[2] === undefined ||
n.ThisExpression.check(expression.arguments[2]))
) {
const old = { inLoop, replaceReturn };
inLoop = false;
replaceReturn = true;
this.visit(
path
.get("expression")
.get("arguments")
.get(1)
.get("body")
);
inLoop = old.inLoop;
replaceReturn = old.replaceReturn;
const [right, { body, params }] = expression.arguments;
const loop = b.forOfStatement(
b.variableDeclaration("let", [
b.variableDeclarator(
valueOnly ? params[0] : b.arrayPattern([params[1], params[0]])
),
]),
valueOnly
? right
: b.callExpression(
b.memberExpression(right, b.identifier("entries")),
[]
),
checkStatement(body) ? body : b.expressionStatement(body)
);
loop.comments = comments;
path.replace(loop);
changed = true;
}
this.traverse(path);
},
visitForStatement: visitLoop("init", "test", "update"),
visitForInStatement: visitLoop("left", "right"),
visitForOfStatement: visitLoop("left", "right"),
visitFunction(path) {
this.visit(path.get("params"));
const old = { replaceReturn };
replaceReturn = false;
this.visit(path.get("body"));
replaceReturn = old.replaceReturn;
return false;
},
visitReturnStatement(path) {
if (replaceReturn) {
assert(!inLoop); // could use labeled continue if this ever fires
const { argument, comments } = path.node;
if (argument === null) {
const s = b.continueStatement();
s.comments = comments;
path.replace(s);
} else {
const s = b.expressionStatement(argument);
s.comments = comments;
path.replace(s, b.continueStatement());
}
return false;
}
this.traverse(path);
},
visitWhileStatement: visitLoop("test"),
});
if (changed) {
console.log("Writing", file);
fs.writeFileSync(file, recast.print(ast).code, { encoding: "utf8" });
}
}
Signed-off-by: Anders Kaseorg <anders@zulipchat.com>
2020-02-06 06:19:47 +01:00
|
|
|
for (const rec of event.subscriptions) {
|
2019-11-02 00:06:25 +01:00
|
|
|
const sub = stream_data.get_sub_by_id(rec.stream_id);
|
2017-05-31 08:53:09 +02:00
|
|
|
stream_events.mark_unsubscribed(sub);
|
js: Automatically convert _.each to for…of.
This commit was automatically generated by the following script,
followed by lint --fix and a few small manual lint-related cleanups.
import * as babelParser from "recast/parsers/babel";
import * as recast from "recast";
import * as tsParser from "recast/parsers/typescript";
import { builders as b, namedTypes as n } from "ast-types";
import { Context } from "ast-types/lib/path-visitor";
import K from "ast-types/gen/kinds";
import { NodePath } from "ast-types/lib/node-path";
import assert from "assert";
import fs from "fs";
import path from "path";
import process from "process";
const checkExpression = (node: n.Node): node is K.ExpressionKind =>
n.Expression.check(node);
const checkStatement = (node: n.Node): node is K.StatementKind =>
n.Statement.check(node);
for (const file of process.argv.slice(2)) {
console.log("Parsing", file);
const ast = recast.parse(fs.readFileSync(file, { encoding: "utf8" }), {
parser: path.extname(file) === ".ts" ? tsParser : babelParser,
});
let changed = false;
let inLoop = false;
let replaceReturn = false;
const visitLoop = (...args: string[]) =>
function(this: Context, path: NodePath) {
for (const arg of args) {
this.visit(path.get(arg));
}
const old = { inLoop };
inLoop = true;
this.visit(path.get("body"));
inLoop = old.inLoop;
return false;
};
recast.visit(ast, {
visitDoWhileStatement: visitLoop("test"),
visitExpressionStatement(path) {
const { expression, comments } = path.node;
let valueOnly;
if (
n.CallExpression.check(expression) &&
n.MemberExpression.check(expression.callee) &&
!expression.callee.computed &&
n.Identifier.check(expression.callee.object) &&
expression.callee.object.name === "_" &&
n.Identifier.check(expression.callee.property) &&
["each", "forEach"].includes(expression.callee.property.name) &&
[2, 3].includes(expression.arguments.length) &&
checkExpression(expression.arguments[0]) &&
(n.FunctionExpression.check(expression.arguments[1]) ||
n.ArrowFunctionExpression.check(expression.arguments[1])) &&
[1, 2].includes(expression.arguments[1].params.length) &&
n.Identifier.check(expression.arguments[1].params[0]) &&
((valueOnly = expression.arguments[1].params[1] === undefined) ||
n.Identifier.check(expression.arguments[1].params[1])) &&
(expression.arguments[2] === undefined ||
n.ThisExpression.check(expression.arguments[2]))
) {
const old = { inLoop, replaceReturn };
inLoop = false;
replaceReturn = true;
this.visit(
path
.get("expression")
.get("arguments")
.get(1)
.get("body")
);
inLoop = old.inLoop;
replaceReturn = old.replaceReturn;
const [right, { body, params }] = expression.arguments;
const loop = b.forOfStatement(
b.variableDeclaration("let", [
b.variableDeclarator(
valueOnly ? params[0] : b.arrayPattern([params[1], params[0]])
),
]),
valueOnly
? right
: b.callExpression(
b.memberExpression(right, b.identifier("entries")),
[]
),
checkStatement(body) ? body : b.expressionStatement(body)
);
loop.comments = comments;
path.replace(loop);
changed = true;
}
this.traverse(path);
},
visitForStatement: visitLoop("init", "test", "update"),
visitForInStatement: visitLoop("left", "right"),
visitForOfStatement: visitLoop("left", "right"),
visitFunction(path) {
this.visit(path.get("params"));
const old = { replaceReturn };
replaceReturn = false;
this.visit(path.get("body"));
replaceReturn = old.replaceReturn;
return false;
},
visitReturnStatement(path) {
if (replaceReturn) {
assert(!inLoop); // could use labeled continue if this ever fires
const { argument, comments } = path.node;
if (argument === null) {
const s = b.continueStatement();
s.comments = comments;
path.replace(s);
} else {
const s = b.expressionStatement(argument);
s.comments = comments;
path.replace(s, b.continueStatement());
}
return false;
}
this.traverse(path);
},
visitWhileStatement: visitLoop("test"),
});
if (changed) {
console.log("Writing", file);
fs.writeFileSync(file, recast.print(ast).code, { encoding: "utf8" });
}
}
Signed-off-by: Anders Kaseorg <anders@zulipchat.com>
2020-02-06 06:19:47 +01:00
|
|
|
}
|
2017-05-31 08:53:09 +02:00
|
|
|
} else if (event.op === 'update') {
|
|
|
|
stream_events.update_property(
|
|
|
|
event.stream_id,
|
|
|
|
event.property,
|
|
|
|
event.value
|
|
|
|
);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 'typing':
|
|
|
|
if (event.sender.user_id === page_params.user_id) {
|
|
|
|
// typing notifications are sent to the user who is typing
|
|
|
|
// as well as recipients; we ignore such self-generated events.
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (event.op === 'start') {
|
|
|
|
typing_events.display_notification(event);
|
|
|
|
} else if (event.op === 'stop') {
|
|
|
|
typing_events.hide_notification(event);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2019-10-25 23:55:37 +02:00
|
|
|
case 'update_display_settings': {
|
2019-11-02 00:06:25 +01:00
|
|
|
const user_display_settings = [
|
2020-05-16 13:13:59 +02:00
|
|
|
'color_scheme',
|
2017-07-18 02:58:13 +02:00
|
|
|
'default_language',
|
2019-03-17 14:48:51 +01:00
|
|
|
'demote_inactive_streams',
|
2018-05-24 20:53:26 +02:00
|
|
|
'dense_mode',
|
2017-07-18 02:58:13 +02:00
|
|
|
'emojiset',
|
2019-06-13 15:21:20 +02:00
|
|
|
'fluid_layout_width',
|
2017-07-18 02:58:13 +02:00
|
|
|
'high_contrast_mode',
|
|
|
|
'left_side_userlist',
|
|
|
|
'timezone',
|
|
|
|
'twenty_four_hour_time',
|
2018-01-15 19:36:32 +01:00
|
|
|
'translate_emoticons',
|
2018-08-17 08:48:12 +02:00
|
|
|
'starred_message_counts',
|
2017-07-18 02:58:13 +02:00
|
|
|
];
|
2020-02-08 04:04:36 +01:00
|
|
|
if (user_display_settings.includes(event.setting_name)) {
|
2017-07-18 02:58:13 +02:00
|
|
|
page_params[event.setting_name] = event.setting;
|
|
|
|
}
|
2018-03-05 03:46:07 +01:00
|
|
|
if (event.setting_name === 'default_language') {
|
|
|
|
// We additionally need to set the language name.
|
|
|
|
page_params.default_language_name = event.language_name;
|
|
|
|
}
|
2017-05-31 08:53:09 +02:00
|
|
|
if (event.setting_name === 'twenty_four_hour_time') {
|
|
|
|
// Rerender the whole message list UI
|
|
|
|
home_msg_list.rerender();
|
|
|
|
if (current_msg_list === message_list.narrowed) {
|
|
|
|
message_list.narrowed.rerender();
|
|
|
|
}
|
|
|
|
}
|
2017-07-07 18:15:10 +02:00
|
|
|
if (event.setting_name === 'high_contrast_mode') {
|
|
|
|
$("body").toggleClass("high-contrast");
|
|
|
|
}
|
2019-03-17 14:48:51 +01:00
|
|
|
if (event.setting_name === 'demote_inactive_streams') {
|
|
|
|
stream_list.update_streams_sidebar();
|
2019-12-27 15:59:42 +01:00
|
|
|
stream_data.set_filter_out_inactives();
|
2019-03-17 14:48:51 +01:00
|
|
|
}
|
2018-05-24 20:53:26 +02:00
|
|
|
if (event.setting_name === 'dense_mode') {
|
|
|
|
$("body").toggleClass("less_dense_mode");
|
|
|
|
$("body").toggleClass("more_dense_mode");
|
|
|
|
}
|
2020-05-16 13:13:59 +02:00
|
|
|
if (event.setting_name === 'color_scheme') {
|
2017-11-14 20:42:31 +01:00
|
|
|
$("body").fadeOut(300);
|
|
|
|
setTimeout(function () {
|
2020-05-16 13:13:59 +02:00
|
|
|
if (event.setting === settings_config.color_scheme_values.night.code) {
|
2017-11-30 02:31:21 +01:00
|
|
|
night_mode.enable();
|
2019-01-27 08:25:10 +01:00
|
|
|
realm_logo.rerender();
|
2020-05-16 13:13:59 +02:00
|
|
|
} else if (event.setting === settings_config.color_scheme_values.day.code) {
|
2017-11-30 02:31:21 +01:00
|
|
|
night_mode.disable();
|
2019-01-27 08:25:10 +01:00
|
|
|
realm_logo.rerender();
|
2020-05-16 13:13:59 +02:00
|
|
|
} else {
|
|
|
|
night_mode.default_preference_checker();
|
|
|
|
realm_logo.rerender();
|
2017-11-30 02:31:21 +01:00
|
|
|
}
|
2017-11-14 20:42:31 +01:00
|
|
|
$("body").fadeIn(300);
|
|
|
|
}, 300);
|
|
|
|
}
|
2018-08-17 08:48:12 +02:00
|
|
|
if (event.setting_name === 'starred_message_counts') {
|
|
|
|
starred_messages.rerender_ui();
|
|
|
|
}
|
2019-04-16 18:46:17 +02:00
|
|
|
if (event.setting_name === 'fluid_layout_width') {
|
|
|
|
scroll_bar.set_layout_width();
|
|
|
|
}
|
2017-05-31 08:53:09 +02:00
|
|
|
if (event.setting_name === 'left_side_userlist') {
|
|
|
|
// TODO: Make this change the view immediately rather
|
|
|
|
// than requiring a reload or page resize.
|
|
|
|
}
|
|
|
|
if (event.setting_name === 'default_language') {
|
templates: Cache translations.
For Manage Streams, when we render the subscriptions
template, a significant amount of time is taken
by the "t" helper.
Obviously for the first call, we expect "t" to be
somewhat expensive, but subsuquent calls should be
fast, but i18next seems to have some overhead.
Also, we can save a tiny bit of overhead (marking it
as a safe string) that comes from our helper.
As an aside, are we sure it's ok to mark translations
as safe strings?
To test before and after, use blueslip.timings before
and after this commit. When I tested with about 300
streams, the difference is pretty striking:
without cache: 100ms
with cache: 20ms
This is particularly interesting, since the subscriptions
templates have long strings for things like the SVG-based
checkmarks, but they're not really the bottleneck.
Unfortunately, this doesn't seem to be a huge win
elsewhere. In some places we don't call "t", but of
course those might change in the future and benefit from
the cache. And in other places we have smart widgets
that avoid rendering all N objects at one (e.g. buddy
list and list_render).
So this might be too big a hammer to speed up one
screen (albeit a really slow one). It's possible
that we should simply move the i18n.t step **outside**
of certain templates to avoid doing them in a loop.
2020-01-15 15:05:17 +01:00
|
|
|
// TODO: Make this change the view immediately rather than
|
|
|
|
// requiring a reload. This is likely fairly difficult,
|
|
|
|
// because various i18n strings are rendered by the
|
|
|
|
// server; we may want to instead just trigger a page
|
|
|
|
// reload.
|
2017-05-31 08:53:09 +02:00
|
|
|
}
|
|
|
|
if (event.setting_name === 'emojiset') {
|
2018-01-02 21:11:23 +01:00
|
|
|
settings_display.report_emojiset_change();
|
|
|
|
|
2018-01-02 13:02:13 +01:00
|
|
|
// Rerender the whole message list UI
|
|
|
|
home_msg_list.rerender();
|
|
|
|
if (current_msg_list === message_list.narrowed) {
|
|
|
|
message_list.narrowed.rerender();
|
|
|
|
}
|
2017-05-31 08:53:09 +02:00
|
|
|
}
|
2018-03-05 03:32:05 +01:00
|
|
|
settings_display.update_page();
|
2017-05-31 08:53:09 +02:00
|
|
|
break;
|
2019-10-25 23:55:37 +02:00
|
|
|
}
|
2017-05-31 08:53:09 +02:00
|
|
|
|
|
|
|
case 'update_global_notifications':
|
|
|
|
notifications.handle_global_notification_updates(event.notification_name,
|
|
|
|
event.setting);
|
2018-03-06 20:51:43 +01:00
|
|
|
settings_notifications.update_page();
|
2019-02-13 10:22:16 +01:00
|
|
|
// TODO: This should also do a refresh of the stream_edit UI
|
|
|
|
// if it's currently displayed, possibly reusing some code
|
|
|
|
// from stream_events.js
|
|
|
|
// (E.g. update_stream_push_notifications).
|
2017-05-31 08:53:09 +02:00
|
|
|
break;
|
|
|
|
|
2019-10-25 23:55:37 +02:00
|
|
|
case 'update_message_flags': {
|
2019-11-02 00:06:25 +01:00
|
|
|
const new_value = event.operation === "add";
|
2017-05-31 08:53:09 +02:00
|
|
|
switch (event.flag) {
|
|
|
|
case 'starred':
|
js: Automatically convert _.each to for…of.
This commit was automatically generated by the following script,
followed by lint --fix and a few small manual lint-related cleanups.
import * as babelParser from "recast/parsers/babel";
import * as recast from "recast";
import * as tsParser from "recast/parsers/typescript";
import { builders as b, namedTypes as n } from "ast-types";
import { Context } from "ast-types/lib/path-visitor";
import K from "ast-types/gen/kinds";
import { NodePath } from "ast-types/lib/node-path";
import assert from "assert";
import fs from "fs";
import path from "path";
import process from "process";
const checkExpression = (node: n.Node): node is K.ExpressionKind =>
n.Expression.check(node);
const checkStatement = (node: n.Node): node is K.StatementKind =>
n.Statement.check(node);
for (const file of process.argv.slice(2)) {
console.log("Parsing", file);
const ast = recast.parse(fs.readFileSync(file, { encoding: "utf8" }), {
parser: path.extname(file) === ".ts" ? tsParser : babelParser,
});
let changed = false;
let inLoop = false;
let replaceReturn = false;
const visitLoop = (...args: string[]) =>
function(this: Context, path: NodePath) {
for (const arg of args) {
this.visit(path.get(arg));
}
const old = { inLoop };
inLoop = true;
this.visit(path.get("body"));
inLoop = old.inLoop;
return false;
};
recast.visit(ast, {
visitDoWhileStatement: visitLoop("test"),
visitExpressionStatement(path) {
const { expression, comments } = path.node;
let valueOnly;
if (
n.CallExpression.check(expression) &&
n.MemberExpression.check(expression.callee) &&
!expression.callee.computed &&
n.Identifier.check(expression.callee.object) &&
expression.callee.object.name === "_" &&
n.Identifier.check(expression.callee.property) &&
["each", "forEach"].includes(expression.callee.property.name) &&
[2, 3].includes(expression.arguments.length) &&
checkExpression(expression.arguments[0]) &&
(n.FunctionExpression.check(expression.arguments[1]) ||
n.ArrowFunctionExpression.check(expression.arguments[1])) &&
[1, 2].includes(expression.arguments[1].params.length) &&
n.Identifier.check(expression.arguments[1].params[0]) &&
((valueOnly = expression.arguments[1].params[1] === undefined) ||
n.Identifier.check(expression.arguments[1].params[1])) &&
(expression.arguments[2] === undefined ||
n.ThisExpression.check(expression.arguments[2]))
) {
const old = { inLoop, replaceReturn };
inLoop = false;
replaceReturn = true;
this.visit(
path
.get("expression")
.get("arguments")
.get(1)
.get("body")
);
inLoop = old.inLoop;
replaceReturn = old.replaceReturn;
const [right, { body, params }] = expression.arguments;
const loop = b.forOfStatement(
b.variableDeclaration("let", [
b.variableDeclarator(
valueOnly ? params[0] : b.arrayPattern([params[1], params[0]])
),
]),
valueOnly
? right
: b.callExpression(
b.memberExpression(right, b.identifier("entries")),
[]
),
checkStatement(body) ? body : b.expressionStatement(body)
);
loop.comments = comments;
path.replace(loop);
changed = true;
}
this.traverse(path);
},
visitForStatement: visitLoop("init", "test", "update"),
visitForInStatement: visitLoop("left", "right"),
visitForOfStatement: visitLoop("left", "right"),
visitFunction(path) {
this.visit(path.get("params"));
const old = { replaceReturn };
replaceReturn = false;
this.visit(path.get("body"));
replaceReturn = old.replaceReturn;
return false;
},
visitReturnStatement(path) {
if (replaceReturn) {
assert(!inLoop); // could use labeled continue if this ever fires
const { argument, comments } = path.node;
if (argument === null) {
const s = b.continueStatement();
s.comments = comments;
path.replace(s);
} else {
const s = b.expressionStatement(argument);
s.comments = comments;
path.replace(s, b.continueStatement());
}
return false;
}
this.traverse(path);
},
visitWhileStatement: visitLoop("test"),
});
if (changed) {
console.log("Writing", file);
fs.writeFileSync(file, recast.print(ast).code, { encoding: "utf8" });
}
}
Signed-off-by: Anders Kaseorg <anders@zulipchat.com>
2020-02-06 06:19:47 +01:00
|
|
|
for (const message_id of event.messages) {
|
2018-08-01 02:29:10 +02:00
|
|
|
message_flags.update_starred_flag(message_id, new_value);
|
js: Automatically convert _.each to for…of.
This commit was automatically generated by the following script,
followed by lint --fix and a few small manual lint-related cleanups.
import * as babelParser from "recast/parsers/babel";
import * as recast from "recast";
import * as tsParser from "recast/parsers/typescript";
import { builders as b, namedTypes as n } from "ast-types";
import { Context } from "ast-types/lib/path-visitor";
import K from "ast-types/gen/kinds";
import { NodePath } from "ast-types/lib/node-path";
import assert from "assert";
import fs from "fs";
import path from "path";
import process from "process";
const checkExpression = (node: n.Node): node is K.ExpressionKind =>
n.Expression.check(node);
const checkStatement = (node: n.Node): node is K.StatementKind =>
n.Statement.check(node);
for (const file of process.argv.slice(2)) {
console.log("Parsing", file);
const ast = recast.parse(fs.readFileSync(file, { encoding: "utf8" }), {
parser: path.extname(file) === ".ts" ? tsParser : babelParser,
});
let changed = false;
let inLoop = false;
let replaceReturn = false;
const visitLoop = (...args: string[]) =>
function(this: Context, path: NodePath) {
for (const arg of args) {
this.visit(path.get(arg));
}
const old = { inLoop };
inLoop = true;
this.visit(path.get("body"));
inLoop = old.inLoop;
return false;
};
recast.visit(ast, {
visitDoWhileStatement: visitLoop("test"),
visitExpressionStatement(path) {
const { expression, comments } = path.node;
let valueOnly;
if (
n.CallExpression.check(expression) &&
n.MemberExpression.check(expression.callee) &&
!expression.callee.computed &&
n.Identifier.check(expression.callee.object) &&
expression.callee.object.name === "_" &&
n.Identifier.check(expression.callee.property) &&
["each", "forEach"].includes(expression.callee.property.name) &&
[2, 3].includes(expression.arguments.length) &&
checkExpression(expression.arguments[0]) &&
(n.FunctionExpression.check(expression.arguments[1]) ||
n.ArrowFunctionExpression.check(expression.arguments[1])) &&
[1, 2].includes(expression.arguments[1].params.length) &&
n.Identifier.check(expression.arguments[1].params[0]) &&
((valueOnly = expression.arguments[1].params[1] === undefined) ||
n.Identifier.check(expression.arguments[1].params[1])) &&
(expression.arguments[2] === undefined ||
n.ThisExpression.check(expression.arguments[2]))
) {
const old = { inLoop, replaceReturn };
inLoop = false;
replaceReturn = true;
this.visit(
path
.get("expression")
.get("arguments")
.get(1)
.get("body")
);
inLoop = old.inLoop;
replaceReturn = old.replaceReturn;
const [right, { body, params }] = expression.arguments;
const loop = b.forOfStatement(
b.variableDeclaration("let", [
b.variableDeclarator(
valueOnly ? params[0] : b.arrayPattern([params[1], params[0]])
),
]),
valueOnly
? right
: b.callExpression(
b.memberExpression(right, b.identifier("entries")),
[]
),
checkStatement(body) ? body : b.expressionStatement(body)
);
loop.comments = comments;
path.replace(loop);
changed = true;
}
this.traverse(path);
},
visitForStatement: visitLoop("init", "test", "update"),
visitForInStatement: visitLoop("left", "right"),
visitForOfStatement: visitLoop("left", "right"),
visitFunction(path) {
this.visit(path.get("params"));
const old = { replaceReturn };
replaceReturn = false;
this.visit(path.get("body"));
replaceReturn = old.replaceReturn;
return false;
},
visitReturnStatement(path) {
if (replaceReturn) {
assert(!inLoop); // could use labeled continue if this ever fires
const { argument, comments } = path.node;
if (argument === null) {
const s = b.continueStatement();
s.comments = comments;
path.replace(s);
} else {
const s = b.expressionStatement(argument);
s.comments = comments;
path.replace(s, b.continueStatement());
}
return false;
}
this.traverse(path);
},
visitWhileStatement: visitLoop("test"),
});
if (changed) {
console.log("Writing", file);
fs.writeFileSync(file, recast.print(ast).code, { encoding: "utf8" });
}
}
Signed-off-by: Anders Kaseorg <anders@zulipchat.com>
2020-02-06 06:19:47 +01:00
|
|
|
}
|
|
|
|
|
2018-08-17 03:46:32 +02:00
|
|
|
if (event.operation === "add") {
|
|
|
|
starred_messages.add(event.messages);
|
|
|
|
} else {
|
|
|
|
starred_messages.remove(event.messages);
|
|
|
|
}
|
2017-05-31 08:53:09 +02:00
|
|
|
break;
|
|
|
|
case 'read':
|
2017-08-03 00:28:16 +02:00
|
|
|
unread_ops.process_read_messages_event(event.messages);
|
2017-05-31 08:53:09 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
2019-10-25 23:55:37 +02:00
|
|
|
}
|
2017-05-31 08:53:09 +02:00
|
|
|
|
2017-11-17 06:15:19 +01:00
|
|
|
case 'user_group':
|
|
|
|
if (event.op === 'add') {
|
|
|
|
user_groups.add(event.group);
|
2018-03-04 17:39:54 +01:00
|
|
|
} else if (event.op === 'add_members') {
|
|
|
|
user_groups.add_members(event.group_id, event.user_ids);
|
|
|
|
} else if (event.op === 'remove_members') {
|
|
|
|
user_groups.remove_members(event.group_id, event.user_ids);
|
2018-03-14 17:52:38 +01:00
|
|
|
} else if (event.op === "update") {
|
|
|
|
user_groups.update(event);
|
2017-11-17 06:15:19 +01:00
|
|
|
}
|
2018-03-04 17:39:54 +01:00
|
|
|
settings_user_groups.reload();
|
2017-11-17 06:15:19 +01:00
|
|
|
break;
|
2018-12-19 18:41:47 +01:00
|
|
|
|
|
|
|
case 'user_status':
|
2019-01-23 19:25:22 +01:00
|
|
|
if (event.away !== undefined) {
|
|
|
|
if (event.away) {
|
|
|
|
activity.on_set_away(event.user_id);
|
|
|
|
} else {
|
|
|
|
activity.on_revoke_away(event.user_id);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-01-25 16:41:30 +01:00
|
|
|
if (event.status_text !== undefined) {
|
2019-01-23 19:25:22 +01:00
|
|
|
user_status.set_status_text({
|
|
|
|
user_id: event.user_id,
|
2019-01-25 16:52:14 +01:00
|
|
|
status_text: event.status_text,
|
2019-01-23 19:25:22 +01:00
|
|
|
});
|
2019-01-25 16:40:18 +01:00
|
|
|
activity.redraw_user(event.user_id);
|
2018-12-19 18:41:47 +01:00
|
|
|
}
|
|
|
|
break;
|
2019-04-09 21:49:07 +02:00
|
|
|
case 'realm_export':
|
|
|
|
settings_exports.populate_exports_table(event.exports);
|
|
|
|
break;
|
2017-05-31 08:53:09 +02:00
|
|
|
}
|
2018-12-19 18:41:47 +01:00
|
|
|
|
2017-05-31 08:53:09 +02:00
|
|
|
};
|
|
|
|
|
2019-10-25 09:45:13 +02:00
|
|
|
window.server_events_dispatch = exports;
|