mirror of
				https://github.com/zulip/zulip.git
				synced 2025-11-03 21:43:21 +00:00 
			
		
		
		
	
				
					committed by
					
						
						Tim Abbott
					
				
			
			
				
	
			
			
			
						parent
						
							e52188bd41
						
					
				
				
					commit
					91d2b5ed81
				
			@@ -1,44 +1,46 @@
 | 
			
		||||
import $ from "jquery";
 | 
			
		||||
 | 
			
		||||
import render_user_group_info_popover from "../templates/user_group_info_popover.hbs";
 | 
			
		||||
import render_user_group_info_popover_content from "../templates/user_group_info_popover_content.hbs";
 | 
			
		||||
 | 
			
		||||
import * as blueslip from "./blueslip";
 | 
			
		||||
import * as buddy_data from "./buddy_data";
 | 
			
		||||
import {media_breakpoints_num} from "./css_variables";
 | 
			
		||||
import * as message_lists from "./message_lists";
 | 
			
		||||
import * as message_viewport from "./message_viewport";
 | 
			
		||||
import * as people from "./people";
 | 
			
		||||
import {hide_all, popover_items_handle_keyboard} from "./popovers";
 | 
			
		||||
import * as popover_menus from "./popover_menus";
 | 
			
		||||
import * as popovers from "./popovers";
 | 
			
		||||
import {popover_items_handle_keyboard} from "./popovers";
 | 
			
		||||
import * as rows from "./rows";
 | 
			
		||||
import * as ui_util from "./ui_util";
 | 
			
		||||
import * as user_groups from "./user_groups";
 | 
			
		||||
import * as util from "./util";
 | 
			
		||||
 | 
			
		||||
let $current_user_group_popover_elem;
 | 
			
		||||
let user_group_popover_instance;
 | 
			
		||||
 | 
			
		||||
export function hide() {
 | 
			
		||||
    if (is_open()) {
 | 
			
		||||
        $current_user_group_popover_elem.popover("destroy");
 | 
			
		||||
        $current_user_group_popover_elem = undefined;
 | 
			
		||||
        user_group_popover_instance.destroy();
 | 
			
		||||
        user_group_popover_instance = undefined;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function is_open() {
 | 
			
		||||
    return $current_user_group_popover_elem !== undefined;
 | 
			
		||||
    return Boolean(user_group_popover_instance);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function get_user_group_popover_items() {
 | 
			
		||||
    if (!$current_user_group_popover_elem) {
 | 
			
		||||
    if (!is_open()) {
 | 
			
		||||
        blueslip.error("Trying to get menu items when user group popover is closed.");
 | 
			
		||||
        return undefined;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const popover_data = $current_user_group_popover_elem.data("popover");
 | 
			
		||||
    if (!popover_data) {
 | 
			
		||||
    const $popover = $(user_group_popover_instance.popper);
 | 
			
		||||
    if (!$popover) {
 | 
			
		||||
        blueslip.error("Cannot find user group popover data");
 | 
			
		||||
        return undefined;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return $("li:not(.divider):visible a", popover_data.$tip);
 | 
			
		||||
    return $("li:not(.divider):visible a", $popover);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function handle_keyboard(key) {
 | 
			
		||||
@@ -49,40 +51,58 @@ export function handle_keyboard(key) {
 | 
			
		||||
// element is the target element to pop off of;
 | 
			
		||||
// message_id is the message id containing it, which should be selected;
 | 
			
		||||
export function toggle_user_group_info_popover(element, message_id) {
 | 
			
		||||
    const $last_popover_elem = $current_user_group_popover_elem;
 | 
			
		||||
    hide_all();
 | 
			
		||||
    if ($last_popover_elem !== undefined && $last_popover_elem.get()[0] === element) {
 | 
			
		||||
        // We want it to be the case that a user can dismiss a popover
 | 
			
		||||
        // by clicking on the same element that caused the popover.
 | 
			
		||||
    if (is_open()) {
 | 
			
		||||
        hide();
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // hardcoded pixel height of the popover
 | 
			
		||||
    // note that the actual size varies (in group size), but this is about as big as it gets
 | 
			
		||||
    const popover_size = 390;
 | 
			
		||||
    const $elt = $(element);
 | 
			
		||||
    const user_group_id = Number.parseInt($elt.attr("data-user-group-id"), 10);
 | 
			
		||||
    const group = user_groups.get_user_group_from_id(user_group_id);
 | 
			
		||||
 | 
			
		||||
    message_lists.current.select_id(message_id);
 | 
			
		||||
    let show_as_overlay = false;
 | 
			
		||||
 | 
			
		||||
    if ($elt.data("popover") === undefined) {
 | 
			
		||||
        const args = {
 | 
			
		||||
            group_name: group.name,
 | 
			
		||||
            group_description: group.description,
 | 
			
		||||
            members: sort_group_members(fetch_group_members([...group.members])),
 | 
			
		||||
        };
 | 
			
		||||
        $elt.popover({
 | 
			
		||||
            placement: calculate_info_popover_placement(popover_size, $elt),
 | 
			
		||||
            template: render_user_group_info_popover(),
 | 
			
		||||
            content: render_user_group_info_popover_content(args),
 | 
			
		||||
            html: true,
 | 
			
		||||
            trigger: "manual",
 | 
			
		||||
            fixed: true,
 | 
			
		||||
        });
 | 
			
		||||
        $elt.popover("show");
 | 
			
		||||
        $current_user_group_popover_elem = $elt;
 | 
			
		||||
    // If the window is mobile-sized, we will render the
 | 
			
		||||
    // user group popover centered on the screen with the overlay.
 | 
			
		||||
    if (window.innerWidth <= media_breakpoints_num.md) {
 | 
			
		||||
        show_as_overlay = true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    popover_menus.toggle_popover_menu(
 | 
			
		||||
        element,
 | 
			
		||||
        {
 | 
			
		||||
            placement: "right",
 | 
			
		||||
            arrow: false,
 | 
			
		||||
            popperOptions: {
 | 
			
		||||
                modifiers: [
 | 
			
		||||
                    {
 | 
			
		||||
                        name: "flip",
 | 
			
		||||
                        options: {
 | 
			
		||||
                            fallbackPlacements: ["left", "top", "bottom"],
 | 
			
		||||
                        },
 | 
			
		||||
                    },
 | 
			
		||||
                ],
 | 
			
		||||
            },
 | 
			
		||||
            onCreate(instance) {
 | 
			
		||||
                popovers.hide_all_except_sidebars();
 | 
			
		||||
                if (message_id) {
 | 
			
		||||
                    message_lists.current.select_id(message_id);
 | 
			
		||||
                }
 | 
			
		||||
                user_group_popover_instance = instance;
 | 
			
		||||
                const $popover = $(instance.popper);
 | 
			
		||||
                $popover.addClass("user-group-popover-root");
 | 
			
		||||
                const args = {
 | 
			
		||||
                    group_name: group.name,
 | 
			
		||||
                    group_description: group.description,
 | 
			
		||||
                    members: sort_group_members(fetch_group_members([...group.members])),
 | 
			
		||||
                };
 | 
			
		||||
                instance.setContent(ui_util.parse_html(render_user_group_info_popover(args)));
 | 
			
		||||
            },
 | 
			
		||||
            onHidden() {
 | 
			
		||||
                hide();
 | 
			
		||||
            },
 | 
			
		||||
        },
 | 
			
		||||
        {show_as_overlay},
 | 
			
		||||
    );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function register_click_handlers() {
 | 
			
		||||
@@ -118,27 +138,11 @@ function sort_group_members(members) {
 | 
			
		||||
    return members.sort((a, b) => util.strcmp(a.full_name, b.fullname));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function calculate_info_popover_placement(size, $elt) {
 | 
			
		||||
    const ypos = $elt.get_offset_to_window().top;
 | 
			
		||||
 | 
			
		||||
    if (!(ypos + size / 2 < message_viewport.height() && ypos > size / 2)) {
 | 
			
		||||
        if (ypos + size < message_viewport.height()) {
 | 
			
		||||
            return "bottom";
 | 
			
		||||
        } else if (ypos > size) {
 | 
			
		||||
            return "top";
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return undefined;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// exporting these functions for testing purposes
 | 
			
		||||
export const _test_fetch_group_members = fetch_group_members;
 | 
			
		||||
 | 
			
		||||
export const _test_sort_group_members = sort_group_members;
 | 
			
		||||
 | 
			
		||||
export const _test_calculate_info_popover_placement = calculate_info_popover_placement;
 | 
			
		||||
 | 
			
		||||
export function initialize() {
 | 
			
		||||
    register_click_handlers();
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -303,6 +303,7 @@ ul {
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.group-info-popover,
 | 
			
		||||
.message-user-card-popover,
 | 
			
		||||
.user-card-popover {
 | 
			
		||||
    width: 240px;
 | 
			
		||||
@@ -669,7 +670,6 @@ ul {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@media (width < $md_min) {
 | 
			
		||||
    .message-user-card-popover,
 | 
			
		||||
    .user-card-popover {
 | 
			
		||||
        display: flex !important;
 | 
			
		||||
        justify-content: center;
 | 
			
		||||
@@ -787,7 +787,8 @@ ul {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.giphy-popover,
 | 
			
		||||
.emoji-popover-root {
 | 
			
		||||
.emoji-popover-root,
 | 
			
		||||
.user-group-popover-root {
 | 
			
		||||
    .tippy-content {
 | 
			
		||||
        /* We remove the default padding from this container
 | 
			
		||||
           as it is not necessary for the Giphy popover. */
 | 
			
		||||
@@ -799,6 +800,19 @@ ul {
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.user-group-popover-root {
 | 
			
		||||
    & .popover-content ul.nav {
 | 
			
		||||
        /* TODO: Clean this logic up after drop Bootstrap styling */
 | 
			
		||||
        margin: 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    & .tippy-box {
 | 
			
		||||
        box-shadow: 0 5px 10px hsl(0deg 0% 0% / 20%);
 | 
			
		||||
        /* User group popover has a bigger border-radius than our usual popovers. */
 | 
			
		||||
        border-radius: 6px;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.emoji-popover-root {
 | 
			
		||||
    /* The emoji popover has a different background color for the
 | 
			
		||||
       header and footer, so we customize the arrow to match this color. */
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,36 @@
 | 
			
		||||
<div class="popover message-user-card-popover group-info-popover">
 | 
			
		||||
<div class="group-info-popover">
 | 
			
		||||
    <div class="popover-inner">
 | 
			
		||||
        <div class="popover-content">
 | 
			
		||||
            <div></div>
 | 
			
		||||
            <div class="group-info">
 | 
			
		||||
                <div class="group-name"> {{group_name}} </div>
 | 
			
		||||
                <div class="group-description">
 | 
			
		||||
                    {{group_description}}
 | 
			
		||||
                </div>
 | 
			
		||||
            </div>
 | 
			
		||||
            <hr />
 | 
			
		||||
            <ul class="nav nav-list member-list" data-simplebar data-simplebar-auto-hide="false">
 | 
			
		||||
                {{#each members}}
 | 
			
		||||
                    <li>
 | 
			
		||||
                        {{#if is_active }}
 | 
			
		||||
                            {{#if is_bot}}
 | 
			
		||||
                            <i class="zulip-icon zulip-icon-bot" aria-hidden="true"></i>
 | 
			
		||||
                            {{else}}
 | 
			
		||||
                            <span class="user_circle {{user_circle_class}}  popover_user_presence" title="{{user_last_seen_time_status}}"></span>
 | 
			
		||||
                            {{/if}}
 | 
			
		||||
                        {{/if}}
 | 
			
		||||
                        <span>{{full_name}}</span>
 | 
			
		||||
                    </li>
 | 
			
		||||
                {{/each}}
 | 
			
		||||
            </ul>
 | 
			
		||||
            <hr />
 | 
			
		||||
            <ul class="nav nav-list manage-group">
 | 
			
		||||
                <li>
 | 
			
		||||
                    <a href="#organization/user-groups-admin">
 | 
			
		||||
                        <i class="fa fa-cog" aria-hidden="true"></i>
 | 
			
		||||
                        {{t 'Manage user groups' }}
 | 
			
		||||
                    </a>
 | 
			
		||||
                </li>
 | 
			
		||||
            </ul>
 | 
			
		||||
        </div>
 | 
			
		||||
    </div>
 | 
			
		||||
</div>
 | 
			
		||||
 
 | 
			
		||||
@@ -1,31 +0,0 @@
 | 
			
		||||
{{! Contents of the "user group info" popup }}
 | 
			
		||||
<div class="group-info">
 | 
			
		||||
    <div class="group-name"> {{group_name}} </div>
 | 
			
		||||
    <div class="group-description">
 | 
			
		||||
        {{group_description}}
 | 
			
		||||
    </div>
 | 
			
		||||
</div>
 | 
			
		||||
<hr />
 | 
			
		||||
<ul class="nav nav-list member-list" data-simplebar data-simplebar-auto-hide="false">
 | 
			
		||||
    {{#each members}}
 | 
			
		||||
        <li>
 | 
			
		||||
            {{#if is_active }}
 | 
			
		||||
                {{#if is_bot}}
 | 
			
		||||
                <i class="zulip-icon zulip-icon-bot" aria-hidden="true"></i>
 | 
			
		||||
                {{else}}
 | 
			
		||||
                <span class="user_circle {{user_circle_class}}  popover_user_presence" title="{{user_last_seen_time_status}}"></span>
 | 
			
		||||
                {{/if}}
 | 
			
		||||
            {{/if}}
 | 
			
		||||
            <span>{{full_name}}</span>
 | 
			
		||||
        </li>
 | 
			
		||||
    {{/each}}
 | 
			
		||||
</ul>
 | 
			
		||||
<hr />
 | 
			
		||||
<ul class="nav nav-list manage-group">
 | 
			
		||||
    <li>
 | 
			
		||||
        <a href="#organization/user-groups-admin">
 | 
			
		||||
            <i class="fa fa-cog" aria-hidden="true"></i>
 | 
			
		||||
            {{t 'Manage user groups' }}
 | 
			
		||||
        </a>
 | 
			
		||||
    </li>
 | 
			
		||||
</ul>
 | 
			
		||||
		Reference in New Issue
	
	Block a user