From 8f716cd64a80eb094f29dbffadcbc81c41da8adf Mon Sep 17 00:00:00 2001 From: Aman Agrawal Date: Sat, 21 Oct 2023 11:57:36 +0000 Subject: [PATCH] help_menu: Extract help items from gear menu into a separate popover. Fixes #27202 --- help/keyboard-shortcuts.md | 2 ++ tools/test-js-with-node | 1 + web/src/navbar_help_menu.js | 52 ++++++++++++++++++++++++++++ web/src/navbar_menus.js | 19 +++++++++- web/src/popover_menus.js | 5 +++ web/src/popover_menus_data.js | 1 - web/src/ui_init.js | 2 ++ web/styles/popovers.css | 4 +++ web/styles/search.css | 8 ----- web/styles/zulip.css | 35 ++++++++++++------- web/templates/gear_menu_popover.hbs | 37 -------------------- web/templates/keyboard_shortcuts.hbs | 4 +++ web/templates/navbar.hbs | 6 ++++ web/templates/navbar_help_menu.hbs | 41 ++++++++++++++++++++++ web/templates/tooltip_templates.hbs | 4 +++ 15 files changed, 162 insertions(+), 59 deletions(-) create mode 100644 web/src/navbar_help_menu.js create mode 100644 web/templates/navbar_help_menu.hbs diff --git a/help/keyboard-shortcuts.md b/help/keyboard-shortcuts.md index 3d739cce62..0ce318c4ea 100644 --- a/help/keyboard-shortcuts.md +++ b/help/keyboard-shortcuts.md @@ -203,6 +203,8 @@ Keyboard navigation (e.g. arrow keys) works as expected. * **Open personal menu**: G + +* **Open help menu**: G + + ### For a selected message (outlined in blue) * **Toggle emoji reactions menu**: : diff --git a/tools/test-js-with-node b/tools/test-js-with-node index 77f780908e..6a788d1ee0 100755 --- a/tools/test-js-with-node +++ b/tools/test-js-with-node @@ -152,6 +152,7 @@ EXEMPT_FILES = make_set( "web/src/narrow_history.js", "web/src/narrow_title.js", "web/src/navbar_alerts.js", + "web/src/navbar_help_menu.js", "web/src/navbar_menus.js", "web/src/navigate.js", "web/src/overlay_util.ts", diff --git a/web/src/navbar_help_menu.js b/web/src/navbar_help_menu.js new file mode 100644 index 0000000000..ee9fe2d5dd --- /dev/null +++ b/web/src/navbar_help_menu.js @@ -0,0 +1,52 @@ +import $ from "jquery"; + +import render_navbar_help_menu from "../templates/navbar_help_menu.hbs"; + +import {page_params} from "./page_params"; +import * as popover_menus from "./popover_menus"; +import {parse_html} from "./ui_util"; + +export function initialize() { + popover_menus.register_popover_menu("#help-menu", { + theme: "navbar-dropdown-menu", + placement: "bottom", + offset: [-50, 0], + // The strategy: "fixed"; and eventlisteners modifier option + // ensure that the personal menu does not modify its position + // or disappear when user zooms the page. + popperOptions: { + strategy: "fixed", + modifiers: [ + { + name: "eventListeners", + options: { + scroll: false, + }, + }, + ], + }, + onMount(instance) { + popover_menus.popover_instances.help_menu = instance; + }, + onShow(instance) { + instance.setContent( + parse_html( + render_navbar_help_menu({ + corporate_enabled: page_params.corporate_enabled, + }), + ), + ); + }, + onHidden(instance) { + instance.destroy(); + popover_menus.popover_instances.help_menu = undefined; + }, + }); +} + +export function toggle() { + // NOTE: Since to open help menu, you need to click on help navbar icon (which calls + // tippyjs.hideAll()), or go via gear menu if using hotkeys, we don't need to + // call tippyjs.hideAll() for it. + $("#help-menu").trigger("click"); +} diff --git a/web/src/navbar_menus.js b/web/src/navbar_menus.js index 4494b5497b..c9843cae70 100644 --- a/web/src/navbar_menus.js +++ b/web/src/navbar_menus.js @@ -1,4 +1,5 @@ import * as gear_menu from "./gear_menu"; +import * as navbar_help_menu from "./navbar_help_menu"; import {page_params} from "./page_params"; import * as personal_menu_popover from "./personal_menu_popover"; import * as popover_menus from "./popover_menus"; @@ -6,7 +7,8 @@ import * as popover_menus from "./popover_menus"; export function is_navbar_menus_displayed() { return ( popover_menus.is_personal_menu_popover_displayed() || - popover_menus.is_gear_menu_popover_displayed() + popover_menus.is_gear_menu_popover_displayed() || + popover_menus.is_help_menu_popover_displayed() ); } @@ -24,6 +26,16 @@ export function handle_keyboard_events(event_name) { return true; } + if ( + popover_menus.is_help_menu_popover_displayed() && + (event_name === "right_arrow" || event_name === "gear_menu") + ) { + // Open gear menu popover on right arrow. + navbar_help_menu.toggle(); + gear_menu.toggle(); + return true; + } + if (popover_menus.is_gear_menu_popover_displayed()) { if (event_name === "gear_menu") { gear_menu.toggle(); @@ -33,6 +45,11 @@ export function handle_keyboard_events(event_name) { gear_menu.toggle(); personal_menu_popover.toggle(); return true; + } else if (event_name === "left_arrow") { + // Open help menu popover on g + left arrow. + gear_menu.toggle(); + navbar_help_menu.toggle(); + return true; } } diff --git a/web/src/popover_menus.js b/web/src/popover_menus.js index fc5025f3d9..69a0e03a50 100644 --- a/web/src/popover_menus.js +++ b/web/src/popover_menus.js @@ -37,6 +37,7 @@ export const popover_instances = { change_visibility_policy: null, personal_menu: null, gear_menu: null, + help_menu: null, }; /* Keyboard UI functions */ @@ -111,6 +112,10 @@ export function get_gear_menu_instance() { return popover_instances.gear_menu; } +export function is_help_menu_popover_displayed() { + return popover_instances.help_menu?.state.isVisible; +} + export function is_message_actions_popover_displayed() { return popover_instances.message_actions?.state.isVisible; } diff --git a/web/src/popover_menus_data.js b/web/src/popover_menus_data.js index 4cb7f149db..fd8ce63bd6 100644 --- a/web/src/popover_menus_data.js +++ b/web/src/popover_menus_data.js @@ -202,7 +202,6 @@ export function get_gear_menu_content_context() { apps_page_url: page_params.apps_page_url, can_create_multiuse_invite: settings_data.user_can_create_multiuse_invite(), can_invite_users_by_email: settings_data.user_can_invite_users_by_email(), - corporate_enabled: page_params.corporate_enabled, is_guest: page_params.is_guest, login_link: page_params.development_environment ? "/devlogin/" : "/login/", promote_sponsoring_zulip: page_params.promote_sponsoring_zulip, diff --git a/web/src/ui_init.js b/web/src/ui_init.js index b51f6ce9a6..e4631d1c94 100644 --- a/web/src/ui_init.js +++ b/web/src/ui_init.js @@ -75,6 +75,7 @@ import * as narrow_history from "./narrow_history"; import * as narrow_state from "./narrow_state"; import * as narrow_title from "./narrow_title"; import * as navbar_alerts from "./navbar_alerts"; +import * as navbar_help_menu from "./navbar_help_menu"; import * as navigate from "./navigate"; import * as overlays from "./overlays"; import {page_params} from "./page_params"; @@ -696,6 +697,7 @@ export function initialize_everything() { }); unread_ops.initialize(); gear_menu.initialize(); + navbar_help_menu.initialize(); giphy.initialize(); presence.initialize(presence_params); settings_display.initialize(); diff --git a/web/styles/popovers.css b/web/styles/popovers.css index c0e948148d..60fb7ec844 100644 --- a/web/styles/popovers.css +++ b/web/styles/popovers.css @@ -1310,6 +1310,10 @@ ul { } } +#help-menu-dropdown { + padding-bottom: 5px; +} + ul.navbar-dropdown-menu-outer-list { list-style: none; margin: 0; diff --git a/web/styles/search.css b/web/styles/search.css index 75cd044e7e..5d5b14e911 100644 --- a/web/styles/search.css +++ b/web/styles/search.css @@ -185,14 +185,6 @@ height: var(--search-box-height); } - @media ($md_min <= width < $xl_min) { - /* Add some space between the search input and the userlist toggle - in this width range so that hover state of userlist-toggle looks good. */ - .navbar-search:not(.expanded) { - right: 2px; - } - } - @media (width >= $md_min) { .navbar-search { background: var(--color-background-search); diff --git a/web/styles/zulip.css b/web/styles/zulip.css index bc0e3409b9..986a9f165c 100644 --- a/web/styles/zulip.css +++ b/web/styles/zulip.css @@ -837,10 +837,11 @@ body.has-overlay-scrollbar { display: flex; justify-content: space-evenly; position: absolute; - top: 10px; - right: 40px; - /* width of right column - width of gear icon - right margin of column-right (250px - 40px -7px) */ - width: 203px; + top: 8px; + /* gear menu + help menu width (40px * 2) */ + right: 80px; + /* width of right column - width of gear icon - right margin of column-right (250px - 40px - 40px -7px) */ + width: 163px; & a { font-size: calc(16em / 14); @@ -2990,9 +2991,11 @@ select.invite-as { .spectator-view { #navbar-middle { - margin-right: 85px; + /* = 40px (width of button) * 3 (number of buttons) + 10px extra margin. */ + margin-right: 130px; } + #help-menu, #gear-menu { position: relative; right: 40px; @@ -3039,7 +3042,8 @@ select.invite-as { } #navbar-middle { - margin-right: 127px; + /* = 40px (width of button) * 4 (number of buttons) + 10px extra margin. */ + margin-right: 170px; } } @@ -3143,16 +3147,19 @@ select.invite-as { .spectator-view { #navbar-middle { - margin-right: 65px; + /* = 30px (width of button) * 3 (number of buttons) + 10px extra margin. */ + margin-right: 100px; } + #help-menu, #gear-menu { - right: 35px; + right: 30px; } } #navbar-middle { - margin-right: 97px; + /* = 30px (width of button) * 4 (number of buttons) + 10px extra margin. */ + margin-right: 130px; } .nav .dropdown-menu { @@ -3412,9 +3419,6 @@ select.invite-as { display: flex; justify-content: center; align-items: center; - position: relative; - top: 0; - right: 0; &:hover, &:focus { @@ -3442,9 +3446,16 @@ select.invite-as { font-size: 18px; } + .zulip-icon-help, .zulip-icon-triple-users { font-size: 20px; } + + .zulip-icon-help { + position: relative; + top: 0.5px; + right: -0.5px; + } } #personal-menu { diff --git a/web/templates/gear_menu_popover.hbs b/web/templates/gear_menu_popover.hbs index 8c4a0d166e..c1834eddfe 100644 --- a/web/templates/gear_menu_popover.hbs +++ b/web/templates/gear_menu_popover.hbs @@ -85,43 +85,6 @@ -