user_profile: Enable dynamic URL generation for "View profile" option.

Clicking on "View profile" option now dynamically generates a URL,
allowing the user profile modal to open. Upon closing the modal,
the URL is reverted back to one that was active before the modal
was opened.

Additionally, It displays a profile access error modal when a user
attempts to either view an inaccessible profile or when an invalid
user id is present in the URL.

Fixes #28445.
This commit is contained in:
Pratik 2024-01-05 20:30:57 +05:30 committed by Tim Abbott
parent 76e86bc8fa
commit cad051e5a6
7 changed files with 49 additions and 16 deletions

View File

@ -60,6 +60,7 @@ export function is_overlay_hash(hash: string): boolean {
"search-operators",
"about-zulip",
"scheduled",
"user",
];
const main_hash = get_hash_category(hash);

View File

@ -18,6 +18,7 @@ import * as modals from "./modals";
import * as narrow from "./narrow";
import * as overlays from "./overlays";
import {page_params} from "./page_params";
import * as people from "./people";
import * as popovers from "./popovers";
import * as recent_view_ui from "./recent_view_ui";
import * as recent_view_util from "./recent_view_util";
@ -31,6 +32,7 @@ import {current_user} from "./state_data";
import * as stream_settings_ui from "./stream_settings_ui";
import * as ui_report from "./ui_report";
import * as user_group_edit from "./user_group_edit";
import * as user_profile from "./user_profile";
import {user_settings} from "./user_settings";
// Read https://zulip.readthedocs.io/en/latest/subsystems/hashchange-system.html
@ -372,6 +374,15 @@ function do_hashchange_overlay(old_hash) {
if (base === "scheduled") {
scheduled_messages_overlay_ui.launch();
}
if (base === "user") {
const user_id = Number.parseInt(hash_parser.get_current_hash_section(), 10);
if (!people.is_known_user_id(user_id)) {
user_profile.show_user_profile_access_error_modal();
} else {
const user = people.get_by_user_id(user_id);
user_profile.show_user_profile(user);
}
}
}
function hashchanged(from_reload, e) {

View File

@ -10,13 +10,8 @@ import * as popover_menus_data from "./popover_menus_data";
import * as popovers from "./popovers";
import {current_user} from "./state_data";
import {parse_html} from "./ui_util";
import * as user_profile from "./user_profile";
import * as user_status from "./user_status";
function elem_to_user_id($elem) {
return Number.parseInt($elem.attr("data-user-id"), 10);
}
export function initialize() {
popover_menus.register_popover_menu("#personal-menu", {
theme: "navbar-dropdown-menu",
@ -59,14 +54,6 @@ export function initialize() {
});
});
$popper.one("click", ".personal-menu-actions .view_full_user_profile", (e) => {
const user_id = elem_to_user_id($(e.target).closest(".personal-menu-actions"));
const user = people.get_by_user_id(user_id);
popovers.hide_all();
user_profile.show_user_profile(user);
e.preventDefault();
});
$popper.one("click", ".narrow-self-direct-message", (e) => {
const user_id = current_user.user_id;
const email = people.get_by_user_id(user_id).email;

View File

@ -10,6 +10,7 @@ import render_user_card_popover_for_unknown_user from "../templates/popovers/use
import render_user_card_popover_manage_menu from "../templates/popovers/user_card/user_card_popover_manage_menu.hbs";
import * as blueslip from "./blueslip";
import * as browser_history from "./browser_history";
import * as buddy_data from "./buddy_data";
import * as channel from "./channel";
import * as compose_actions from "./compose_actions";
@ -739,8 +740,7 @@ function register_click_handlers() {
$("body").on("click", ".user-card-popover-actions .view_full_user_profile", (e) => {
const user_id = elem_to_user_id($(e.target).parents("ul"));
const user = people.get_by_user_id(user_id);
user_profile.show_user_profile(user);
browser_history.go_to_location(`user/${user_id}`);
e.stopPropagation();
e.preventDefault();
});

View File

@ -1,6 +1,7 @@
import {parseISO} from "date-fns";
import $ from "jquery";
import render_profile_access_error_model from "../templates/profile_access_error_modal.hbs";
import render_admin_human_form from "../templates/settings/admin_human_form.hbs";
import render_edit_bot_form from "../templates/settings/edit_bot_form.hbs";
import render_settings_edit_embedded_bot_service from "../templates/settings/edit_embedded_bot_service.hbs";
@ -323,6 +324,7 @@ export function hide_user_profile() {
function on_user_profile_hide() {
user_streams_list_widget = undefined;
user_profile_subscribe_widget = undefined;
browser_history.exit_overlay();
}
function show_manage_user_tab(target) {
@ -343,6 +345,18 @@ function initialize_user_type_fields(user) {
}
}
export function show_user_profile_access_error_modal() {
$("body").append(render_profile_access_error_model());
// This opens the model, referencing it by it's ID('profile_access_error_model)
modals.open("profile_access_error_modal", {
autoremove: true,
on_hide() {
browser_history.exit_overlay();
},
});
}
export function show_user_profile(user, default_tab_key = "profile-tab") {
const field_types = realm.custom_profile_field_types;
const profile_data = realm.custom_profile_fields

View File

@ -87,7 +87,7 @@
<li class="navbar-dropdown-menu-outer-list-item">
<ul class="navbar-dropdown-menu-inner-list">
<li class="link-item navbar-dropdown-menu-inner-list-item">
<a tabindex="0" class="view_full_user_profile navbar-dropdown-menu-link">
<a href="#user/{{user_id}}" tabindex="0" class="view_full_user_profile navbar-dropdown-menu-link">
<i class="navbar-dropdown-icon zulip-icon zulip-icon-account"></i>
{{#tr}}View your profile{{/tr}}
</a>

View File

@ -0,0 +1,20 @@
<div class="micromodal" id="profile_access_error_modal" aria-hidden="true">
<div class="modal__overlay" tabindex="-1">
<div class="modal__container" role="dialog" aria-modal="true" aria-labelledby="profile_access_error_modal_label">
<header class="modal__header">
<h1 class="modal__title" id="profile_access_error_modal_label">
{{t "No user found" }}
</h1>
<button class="modal__close" aria-label="{{t 'Close modal' }}" data-micromodal-close></button>
</header>
<main class="modal__content">
<p>
{{t "Either this user does not exist, or you do not have access to their profile." }}
</p>
</main>
<footer class="modal__footer">
<button type="button" class="modal__btn dialog_exit_button" aria-label="{{t 'Close this dialog window' }}" data-micromodal-close>{{t "Close" }}</button>
</footer>
</div>
</div>
</div>