mirror of https://github.com/zulip/zulip.git
parent
e52188bd41
commit
91d2b5ed81
|
@ -1,44 +1,46 @@
|
||||||
import $ from "jquery";
|
import $ from "jquery";
|
||||||
|
|
||||||
import render_user_group_info_popover from "../templates/user_group_info_popover.hbs";
|
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 blueslip from "./blueslip";
|
||||||
import * as buddy_data from "./buddy_data";
|
import * as buddy_data from "./buddy_data";
|
||||||
|
import {media_breakpoints_num} from "./css_variables";
|
||||||
import * as message_lists from "./message_lists";
|
import * as message_lists from "./message_lists";
|
||||||
import * as message_viewport from "./message_viewport";
|
|
||||||
import * as people from "./people";
|
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 rows from "./rows";
|
||||||
|
import * as ui_util from "./ui_util";
|
||||||
import * as user_groups from "./user_groups";
|
import * as user_groups from "./user_groups";
|
||||||
import * as util from "./util";
|
import * as util from "./util";
|
||||||
|
|
||||||
let $current_user_group_popover_elem;
|
let user_group_popover_instance;
|
||||||
|
|
||||||
export function hide() {
|
export function hide() {
|
||||||
if (is_open()) {
|
if (is_open()) {
|
||||||
$current_user_group_popover_elem.popover("destroy");
|
user_group_popover_instance.destroy();
|
||||||
$current_user_group_popover_elem = undefined;
|
user_group_popover_instance = undefined;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function is_open() {
|
export function is_open() {
|
||||||
return $current_user_group_popover_elem !== undefined;
|
return Boolean(user_group_popover_instance);
|
||||||
}
|
}
|
||||||
|
|
||||||
function get_user_group_popover_items() {
|
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.");
|
blueslip.error("Trying to get menu items when user group popover is closed.");
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
const popover_data = $current_user_group_popover_elem.data("popover");
|
const $popover = $(user_group_popover_instance.popper);
|
||||||
if (!popover_data) {
|
if (!$popover) {
|
||||||
blueslip.error("Cannot find user group popover data");
|
blueslip.error("Cannot find user group popover data");
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $("li:not(.divider):visible a", popover_data.$tip);
|
return $("li:not(.divider):visible a", $popover);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function handle_keyboard(key) {
|
export function handle_keyboard(key) {
|
||||||
|
@ -49,40 +51,58 @@ export function handle_keyboard(key) {
|
||||||
// element is the target element to pop off of;
|
// element is the target element to pop off of;
|
||||||
// message_id is the message id containing it, which should be selected;
|
// message_id is the message id containing it, which should be selected;
|
||||||
export function toggle_user_group_info_popover(element, message_id) {
|
export function toggle_user_group_info_popover(element, message_id) {
|
||||||
const $last_popover_elem = $current_user_group_popover_elem;
|
if (is_open()) {
|
||||||
hide_all();
|
hide();
|
||||||
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.
|
|
||||||
return;
|
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 $elt = $(element);
|
||||||
const user_group_id = Number.parseInt($elt.attr("data-user-group-id"), 10);
|
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);
|
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) {
|
// 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 = {
|
const args = {
|
||||||
group_name: group.name,
|
group_name: group.name,
|
||||||
group_description: group.description,
|
group_description: group.description,
|
||||||
members: sort_group_members(fetch_group_members([...group.members])),
|
members: sort_group_members(fetch_group_members([...group.members])),
|
||||||
};
|
};
|
||||||
$elt.popover({
|
instance.setContent(ui_util.parse_html(render_user_group_info_popover(args)));
|
||||||
placement: calculate_info_popover_placement(popover_size, $elt),
|
},
|
||||||
template: render_user_group_info_popover(),
|
onHidden() {
|
||||||
content: render_user_group_info_popover_content(args),
|
hide();
|
||||||
html: true,
|
},
|
||||||
trigger: "manual",
|
},
|
||||||
fixed: true,
|
{show_as_overlay},
|
||||||
});
|
);
|
||||||
$elt.popover("show");
|
|
||||||
$current_user_group_popover_elem = $elt;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function register_click_handlers() {
|
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));
|
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
|
// exporting these functions for testing purposes
|
||||||
export const _test_fetch_group_members = fetch_group_members;
|
export const _test_fetch_group_members = fetch_group_members;
|
||||||
|
|
||||||
export const _test_sort_group_members = sort_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() {
|
export function initialize() {
|
||||||
register_click_handlers();
|
register_click_handlers();
|
||||||
}
|
}
|
||||||
|
|
|
@ -303,6 +303,7 @@ ul {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.group-info-popover,
|
||||||
.message-user-card-popover,
|
.message-user-card-popover,
|
||||||
.user-card-popover {
|
.user-card-popover {
|
||||||
width: 240px;
|
width: 240px;
|
||||||
|
@ -669,7 +670,6 @@ ul {
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (width < $md_min) {
|
@media (width < $md_min) {
|
||||||
.message-user-card-popover,
|
|
||||||
.user-card-popover {
|
.user-card-popover {
|
||||||
display: flex !important;
|
display: flex !important;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
@ -787,7 +787,8 @@ ul {
|
||||||
}
|
}
|
||||||
|
|
||||||
.giphy-popover,
|
.giphy-popover,
|
||||||
.emoji-popover-root {
|
.emoji-popover-root,
|
||||||
|
.user-group-popover-root {
|
||||||
.tippy-content {
|
.tippy-content {
|
||||||
/* We remove the default padding from this container
|
/* We remove the default padding from this container
|
||||||
as it is not necessary for the Giphy popover. */
|
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 {
|
.emoji-popover-root {
|
||||||
/* The emoji popover has a different background color for the
|
/* The emoji popover has a different background color for the
|
||||||
header and footer, so we customize the arrow to match this color. */
|
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-inner">
|
||||||
<div class="popover-content">
|
<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>
|
</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