From 719518babafeffd181b171469c864cd40a1e0bcb Mon Sep 17 00:00:00 2001 From: opmkumar Date: Tue, 10 Sep 2024 22:00:14 +0530 Subject: [PATCH] popovers: Add stream-info-popover when channel pill is clicked. Shows a stream info popover whenever a channel pill is clicked (such as in the pill widgets for adding subscribers to a channel or invitations). The stream info popover contains channel icon and name, channel description and a link to channel settings. Fixes #30567. --- tools/test-js-with-node | 1 + web/src/popover_menus.ts | 2 + web/src/stream_card_popover.ts | 66 +++++++++++++++++++ web/src/stream_pill.ts | 1 + web/src/ui_init.js | 2 + web/styles/app_variables.css | 1 + web/styles/popovers.css | 13 +++- web/templates/input_pill.hbs | 2 +- .../popovers/stream_card_popover.hbs | 23 +++++++ web/tests/stream_pill.test.js | 2 +- 10 files changed, 110 insertions(+), 3 deletions(-) create mode 100644 web/src/stream_card_popover.ts create mode 100644 web/templates/popovers/stream_card_popover.hbs diff --git a/tools/test-js-with-node b/tools/test-js-with-node index 8400687832..233ca14ecd 100755 --- a/tools/test-js-with-node +++ b/tools/test-js-with-node @@ -236,6 +236,7 @@ EXEMPT_FILES = make_set( "web/src/spoilers.ts", "web/src/starred_messages_ui.ts", "web/src/state_data.ts", + "web/src/stream_card_popover.ts", "web/src/stream_color.ts", "web/src/stream_color_events.ts", "web/src/stream_create.js", diff --git a/web/src/popover_menus.ts b/web/src/popover_menus.ts index 59467028dc..d9fd6b292a 100644 --- a/web/src/popover_menus.ts +++ b/web/src/popover_menus.ts @@ -21,6 +21,7 @@ type PopoverName = | "left_sidebar_recent_view_popover" | "top_left_sidebar" | "message_actions" + | "stream_card_popover" | "stream_settings" | "topics_menu" | "send_later" @@ -38,6 +39,7 @@ export const popover_instances: Record = { left_sidebar_recent_view_popover: null, top_left_sidebar: null, message_actions: null, + stream_card_popover: null, stream_settings: null, topics_menu: null, send_later: null, diff --git a/web/src/stream_card_popover.ts b/web/src/stream_card_popover.ts new file mode 100644 index 0000000000..9738f07847 --- /dev/null +++ b/web/src/stream_card_popover.ts @@ -0,0 +1,66 @@ +import $ from "jquery"; +import assert from "minimalistic-assert"; + +import render_stream_card_popover from "../templates/popovers/stream_card_popover.hbs"; + +import * as browser_history from "./browser_history"; +import * as hash_util from "./hash_util"; +import * as modals from "./modals"; +import * as popover_menus from "./popover_menus"; +import {current_user} from "./state_data"; +import * as stream_data from "./stream_data"; +import * as sub_store from "./sub_store"; +import * as ui_util from "./ui_util"; + +let stream_id: number | undefined; + +export function initialize(): void { + popover_menus.register_popover_menu(".pill[data-stream-id]", { + theme: "popover-menu", + placement: "right", + onShow(instance) { + popover_menus.popover_instances.stream_card_popover = instance; + popover_menus.on_show_prep(instance); + + const $elt = $(instance.reference); + const stream_id_str = $elt.attr("data-stream-id"); + assert(stream_id_str !== undefined); + stream_id = Number.parseInt(stream_id_str, 10); + + instance.setContent( + ui_util.parse_html( + render_stream_card_popover({ + stream: { + ...sub_store.get(stream_id), + }, + }), + ), + ); + }, + onMount(instance) { + const $popper = $(instance.popper); + + // Stream settings + $popper.on("click", ".open_stream_settings", () => { + assert(stream_id !== undefined); + const sub = sub_store.get(stream_id); + assert(sub !== undefined); + popover_menus.hide_current_popover_if_visible(instance); + // modals.close_active_if_any() is mainly used to handle navigation to channel settings + // using the popover that is opened when clicking on channel pills in the invite user modal. + modals.close_active_if_any(); + const can_change_name_description = current_user.is_admin; + const can_change_stream_permissions = stream_data.can_change_permissions(sub); + let stream_edit_hash = hash_util.channels_settings_edit_url(sub, "general"); + if (!can_change_stream_permissions && !can_change_name_description) { + stream_edit_hash = hash_util.channels_settings_edit_url(sub, "personal"); + } + browser_history.go_to_location(stream_edit_hash); + }); + }, + onHidden(instance) { + instance.destroy(); + popover_menus.popover_instances.stream_card_popover = null; + }, + }); +} diff --git a/web/src/stream_pill.ts b/web/src/stream_pill.ts index 0414543ed7..25f33d36d6 100644 --- a/web/src/stream_pill.ts +++ b/web/src/stream_pill.ts @@ -96,6 +96,7 @@ export function generate_pill_html(item: StreamPill): string { has_stream: true, stream, display_value: get_display_value_from_item(item), + stream_id: item.stream_id, }); } diff --git a/web/src/ui_init.js b/web/src/ui_init.js index 2dbeca0222..a22ff92bdb 100644 --- a/web/src/ui_init.js +++ b/web/src/ui_init.js @@ -115,6 +115,7 @@ import * as spoilers from "./spoilers"; import * as starred_messages from "./starred_messages"; import * as starred_messages_ui from "./starred_messages_ui"; import {current_user, realm, set_current_user, set_realm, state_data_schema} from "./state_data"; +import * as stream_card_popover from "./stream_card_popover"; import * as stream_data from "./stream_data"; import * as stream_edit from "./stream_edit"; import * as stream_edit_subscribers from "./stream_edit_subscribers"; @@ -533,6 +534,7 @@ export function initialize_everything(state_data) { stream_edit_subscribers.initialize(); stream_data.initialize(state_data.stream_data); user_group_edit_members.initialize(); + stream_card_popover.initialize(); pm_conversations.recent.initialize(state_data.pm_conversations); user_topics.initialize(state_data.user_topics); muted_users.initialize(state_data.muted_users); diff --git a/web/styles/app_variables.css b/web/styles/app_variables.css index 49161665ec..434c6fc24d 100644 --- a/web/styles/app_variables.css +++ b/web/styles/app_variables.css @@ -281,6 +281,7 @@ --user-group-info-popover-min-width: 16.4285em; /* 230px / 14px em */ --topic-actions-popover-min-width: 200px; --user-card-popover-min-width: 200px; + --stream-card-popover-min-width: 16.4285em; /* Information density and typography values */ /* The legacy values here are updated via JavaScript */ diff --git a/web/styles/popovers.css b/web/styles/popovers.css index 8de92a9ce9..83eb2b2d4a 100644 --- a/web/styles/popovers.css +++ b/web/styles/popovers.css @@ -246,7 +246,8 @@ z-index: 106; } -#stream-actions-menu-popover { +#stream-actions-menu-popover, +#stream-card-popover { .popover-stream-name { font-weight: 600; color: var(--color-text-popover-menu); @@ -265,6 +266,10 @@ margin: 0 !important; } + .popover-stream-info-menu-description { + color: var(--color-text-popover-menu); + } + .colorpicker-container { display: none; margin-right: 10px; @@ -1336,6 +1341,12 @@ ul.popover-group-menu-member-list { } } +#stream-card-popover { + .simplebar-content { + min-width: var(--stream-card-popover-min-width); + } +} + .personal-menu-clear-status { display: flex; align-items: center; diff --git a/web/templates/input_pill.hbs b/web/templates/input_pill.hbs index c3ea56a0b8..3ef2ba42a7 100644 --- a/web/templates/input_pill.hbs +++ b/web/templates/input_pill.hbs @@ -1,4 +1,4 @@ -
+
{{#if has_image}} {{/if}} diff --git a/web/templates/popovers/stream_card_popover.hbs b/web/templates/popovers/stream_card_popover.hbs new file mode 100644 index 0000000000..3ccbee74a4 --- /dev/null +++ b/web/templates/popovers/stream_card_popover.hbs @@ -0,0 +1,23 @@ +
+ +
diff --git a/web/tests/stream_pill.test.js b/web/tests/stream_pill.test.js index 7d9550535b..7183d49f33 100644 --- a/web/tests/stream_pill.test.js +++ b/web/tests/stream_pill.test.js @@ -118,7 +118,7 @@ run_test("get_stream_ids", () => { run_test("generate_pill_html", () => { assert.deepEqual( stream_pill.generate_pill_html(denmark_pill), - "
\n" + + "
\n" + ' \n' + ' \n' + ' translated: Denmark: 3 users\n' +