mirror of https://github.com/zulip/zulip.git
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>
|
Loading…
Reference in New Issue