/
githubmirror
/
zulip
Обзор
Документация
Войти
/
githubmirror
/
zulip
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
web/src/user_events.ts
303 строки
13 KB
Anders Kaseorg
web: Use named import for jQuery.
29 июл 2026, 02:35
29 июл 2026, 02:35
52a10e8
Код
Авторство
О чём код?
// This module is kind of small, but it will help us keep // server_events.js simple while breaking some circular // dependencies that existed when this code was in people.js. // (We should do bot updates here too.) import {$} from "jquery"; import assert from "minimalistic-assert"; import * as z from "zod/mini"; import * as activity_ui from "./activity_ui.ts"; import * as blueslip from "./blueslip.ts"; import * as bot_data from "./bot_data.ts"; import {buddy_list} from "./buddy_list.ts"; import * as compose_pm_pill from "./compose_pm_pill.ts"; import * as compose_recipient from "./compose_recipient.ts"; import * as message_live_update from "./message_live_update.ts"; import * as message_view_header from "./message_view_header.ts"; import * as navbar_alerts from "./navbar_alerts.ts"; import * as people from "./people.ts"; import * as pm_list from "./pm_list.ts"; import * as reactions from "./reactions.ts"; import * as settings from "./settings.ts"; import * as settings_account from "./settings_account.ts"; import * as settings_bots from "./settings_bots.ts"; import * as settings_config from "./settings_config.ts"; import * as settings_exports from "./settings_exports.ts"; import * as settings_linkifiers from "./settings_linkifiers.ts"; import * as settings_org from "./settings_org.ts"; import * as settings_panel_menu from "./settings_panel_menu.ts"; import * as settings_preferences from "./settings_preferences.ts"; import * as settings_profile_fields from "./settings_profile_fields.ts"; import * as settings_realm_user_settings_defaults from "./settings_realm_user_settings_defaults.ts"; import * as settings_streams from "./settings_streams.ts"; import * as settings_users from "./settings_users.ts"; import {current_user, realm} from "./state_data.ts"; import * as stream_events from "./stream_events.ts"; import * as user_group_edit from "./user_group_edit.ts"; import * as user_profile from "./user_profile.ts"; export const user_update_schema = z.intersection( z.object({user_id: z.number()}), z.union([ z.object({ avatar_source: z.string(), avatar_url: z.nullable(z.string()), avatar_url_medium: z.nullable(z.string()), avatar_version: z.number(), }), z.object({bot_owner_id: z.number()}), z.object({ custom_profile_field: z.object({ id: z.number(), value: z.nullable(z.string()), rendered_value: z.optional(z.string()), }), }), z.object({delivery_email: z.nullable(z.string())}), z.object({new_email: z.string()}), z.object({full_name: z.string()}), z.object({role: z.number()}), z.object({email: z.string(), timezone: z.string()}), z.object({is_active: z.boolean()}), ]), ); type UserUpdate = z.output<typeof user_update_schema>; export const update_person = function update(event: UserUpdate): void { const user = people.maybe_get_user_by_id(event.user_id); if (!user) { blueslip.error("Got update_person event for unexpected user", {user_id: event.user_id}); return; } if ("new_email" in event) { const user_id = event.user_id; const new_email = event.new_email; people.update_email(user_id, new_email); if (people.is_my_user_id(event.user_id)) { current_user.email = new_email; } } if ("delivery_email" in event) { const delivery_email = event.delivery_email; user.delivery_email = delivery_email; user_profile.update_profile_modal_ui(user, event); if (people.is_my_user_id(event.user_id)) { assert(delivery_email !== null); settings_account.update_email(delivery_email); current_user.delivery_email = delivery_email; settings_account.hide_confirm_email_banner(); } if (user.is_bot && bot_data.get(event.user_id) !== undefined) { assert(delivery_email !== null); bot_data.update(event.user_id, {user_id: event.user_id, email: delivery_email}); } } if ("full_name" in event) { people.set_full_name(user, event.full_name); settings_users.update_user_data(event.user_id, event); activity_ui.redraw(); message_live_update.update_user_full_name(event.user_id, event.full_name); reactions.update_user_full_name(event.user_id); pm_list.update_private_messages(); message_view_header.maybe_update_navbar_title_for_user(event.user_id); compose_recipient.update_user_name_in_compose(event.user_id, event.full_name); user_profile.update_profile_modal_ui(user, event); if (people.is_my_user_id(event.user_id)) { current_user.full_name = event.full_name; settings_account.update_full_name(event.full_name); settings_preferences.update_user_list_style_preview_name(event.full_name); } if (user.is_bot && bot_data.get(event.user_id) !== undefined) { bot_data.update(event.user_id, {user_id: event.user_id, full_name: event.full_name}); } } if ("role" in event) { const was_owner = user.is_owner; user.role = event.role; user.is_owner = event.role === settings_config.user_role_values.owner.code; user.is_admin = event.role === settings_config.user_role_values.admin.code || user.is_owner; user.is_guest = event.role === settings_config.user_role_values.guest.code; user.is_moderator = user.is_admin || event.role === settings_config.user_role_values.moderator.code; settings_users.update_user_data(event.user_id, event); user_profile.update_profile_modal_ui(user, event); settings_account.set_user_own_role_dropdown_value(); if (people.is_my_user_id(event.user_id) && current_user.is_guest !== user.is_guest) { current_user.is_guest = user.is_guest; if (current_user.is_guest) { settings_panel_menu.hide_default_streams_list_for_guest(); } } if (people.is_my_user_id(event.user_id)) { settings_account.update_role_text(); } if (people.is_my_user_id(event.user_id) && current_user.is_owner !== user.is_owner) { current_user.is_owner = user.is_owner; settings_org.maybe_disable_widgets(); settings_org.enable_or_disable_group_permission_settings(); settings.update_lock_icon_in_sidebar(); settings_account.add_or_remove_owner_from_role_dropdown(); settings_account.update_user_own_role_dropdown_state(); } if (people.is_my_user_id(event.user_id) && current_user.is_admin !== user.is_admin) { current_user.is_admin = user.is_admin; settings_linkifiers.maybe_disable_widgets(); settings_org.maybe_disable_widgets(); settings_org.enable_or_disable_group_permission_settings(); settings_profile_fields.maybe_disable_widgets(); settings_realm_user_settings_defaults.maybe_disable_widgets(); settings_streams.rerender_default_streams_for_role_change(); settings_account.update_account_settings_display(); settings.update_lock_icon_in_sidebar(); settings_account.update_user_own_role_dropdown_state(); } if ( !people.is_my_user_id(event.user_id) && was_owner !== user.is_owner && current_user.is_owner ) { settings_account.update_user_own_role_dropdown_state(); } if ( people.is_my_user_id(event.user_id) && current_user.is_moderator !== user.is_moderator ) { current_user.is_moderator = user.is_moderator; } } if ("avatar_url" in event) { const url = event.avatar_url; user.avatar_url = url; user.avatar_version = event.avatar_version; if (people.is_my_user_id(event.user_id)) { current_user.avatar_source = event.avatar_source; current_user.avatar_url = url; current_user.avatar_url_medium = event.avatar_url_medium; $("#user-avatar-upload-widget .image-block").attr("src", event.avatar_url_medium); $("#personal-menu-dropdown .avatar-image, .header-button-avatar-image").attr( "src", `${event.avatar_url_medium}`, ); if (current_user.avatar_source === "G") { $("#user-avatar-source").show(); } else { $("#user-avatar-source").hide(); } settings_preferences.update_user_list_style_preview_avatar( people.small_avatar_url_for_person(user), ); } message_live_update.update_avatar(user.user_id, event.avatar_url); buddy_list.insert_or_move([event.user_id]); user_profile.update_profile_modal_ui(user, event); } if ("custom_profile_field" in event) { people.set_custom_profile_field_data(event.user_id, event.custom_profile_field); user_profile.update_user_custom_profile_fields(user); if (event.user_id === people.my_current_user_id()) { navbar_alerts.maybe_toggle_empty_required_profile_fields_banner(); const field_id = event.custom_profile_field.id; const field_value = people.get_custom_profile_data(event.user_id, field_id)?.value; const is_field_required = realm.custom_profile_fields?.find( (f) => field_id === f.id, )?.required; if (is_field_required) { const $custom_user_field = $( `.profile-settings-form .custom_user_field[data-field-id="${CSS.escape(`${field_id}`)}"]`, ); const $field = $custom_user_field.find(".settings-profile-user-field"); const $required_symbol = $custom_user_field.find(".required-symbol"); if (!field_value) { if (!$field.hasClass("empty-required-field")) { $field.addClass("empty-required-field"); $required_symbol.removeClass("hidden"); } } else { if ($field.hasClass("empty-required-field")) { $field.removeClass("empty-required-field"); $required_symbol.addClass("hidden"); } } } } } if ("timezone" in event) { user.timezone = event.timezone; } if ("bot_owner_id" in event) { assert(user.is_bot); user.bot_owner_id = event.bot_owner_id; user_profile.update_profile_modal_ui(user, event); if (current_user.is_admin) { // Non-admins only have bots they own in bot_data, and receive // realm_bot/add or realm_bot/delete events when ownership changes, // so their bot_data is already up to date at this point. bot_data.update(event.user_id, {user_id: event.user_id, owner_id: event.bot_owner_id}); } settings_bots.redraw_your_bots_list(); settings_bots.toggle_bot_config_download_container(); } if ("is_active" in event) { const is_bot_user = user.is_bot; if (is_bot_user && bot_data.get(event.user_id) !== undefined) { bot_data.update(event.user_id, {user_id: event.user_id, is_active: event.is_active}); } if (event.is_active) { people.add_active_user(user); settings_users.update_view_on_reactivate(event.user_id, is_bot_user); } else { people.deactivate(user); // We used to remove deactivated users in this code block before. But now, // that should be done by the `peer_remove` event being sent by the server. // This function should be removed altogether if we go through a period of // no blueslip errors raised in the function below. stream_events.report_error_if_user_still_has_subscriptions(event.user_id); user_group_edit.remove_deactivated_user_from_all_groups(event.user_id); settings_users.update_view_on_deactivate(event.user_id, is_bot_user); } buddy_list.insert_or_move([event.user_id]); // Update UI elements to reflect the user's deactivated/reactivated status pm_list.update_private_messages(); compose_pm_pill.update_user_pill_active_status(user, event.is_active); settings_account.maybe_update_deactivate_account_button(); if (is_bot_user) { settings_bots.update_bot_data(event.user_id); settings_bots.toggle_bot_config_download_container(); } else if (!event.is_active) { // A human user deactivated, update 'Export permissions' table. settings_exports.remove_export_consent_data_and_redraw(event.user_id); } if (user.is_imported_stub) { settings_panel_menu.update_imported_users_tab(); } } if ("is_imported_stub" in event) { user.is_imported_stub = false; settings_panel_menu.update_imported_users_tab(true, true); } };