hotspots: Move compute_placement to only module using it.

Previously, this function was used by other bootstrap popovers, but
such popovers have all been migrated to Tippy.

Hotspots uses some of that machinery but I think doesn't actually use
the Bootstrap popovers system.
This commit is contained in:
Tim Abbott 2023-09-22 11:13:25 -07:00
parent d6884399b2
commit 1c1d31deec
2 changed files with 46 additions and 57 deletions

View File

@ -7,9 +7,9 @@ import render_hotspot_overlay from "../templates/hotspot_overlay.hbs";
import * as blueslip from "./blueslip";
import * as channel from "./channel";
import * as message_viewport from "./message_viewport";
import * as overlays from "./overlays";
import {page_params} from "./page_params";
import * as popovers from "./popovers";
// popover orientations
const TOP = "top";
@ -19,8 +19,8 @@ const BOTTOM = "bottom";
const LEFT_BOTTOM = "left_bottom";
const VIEWPORT_CENTER = "viewport_center";
// popover orientation can optionally be fixed here (property: popover),
// otherwise popovers.compute_placement is used to compute orientation
// popover orientation can optionally be fixed here to override the
// defaults calculated by compute_placement.
const HOTSPOT_LOCATIONS = new Map([
[
"intro_streams",
@ -61,6 +61,48 @@ const meta = {
opened_hotspot_name: null,
};
function compute_placement($elt, popover_height, popover_width, prefer_vertical_positioning) {
const client_rect = $elt.get(0).getBoundingClientRect();
const distance_from_top = client_rect.top;
const distance_from_bottom = message_viewport.height() - client_rect.bottom;
const distance_from_left = client_rect.left;
const distance_from_right = message_viewport.width() - client_rect.right;
const elt_will_fit_horizontally =
distance_from_left + $elt.width() / 2 > popover_width / 2 &&
distance_from_right + $elt.width() / 2 > popover_width / 2;
const elt_will_fit_vertically =
distance_from_bottom + $elt.height() / 2 > popover_height / 2 &&
distance_from_top + $elt.height() / 2 > popover_height / 2;
// default to placing the popover in the center of the screen
let placement = "viewport_center";
// prioritize left/right over top/bottom
if (distance_from_top > popover_height && elt_will_fit_horizontally) {
placement = "top";
}
if (distance_from_bottom > popover_height && elt_will_fit_horizontally) {
placement = "bottom";
}
if (prefer_vertical_positioning && placement !== "viewport_center") {
// If vertical positioning is preferred and the popover fits in
// either top or bottom position then return.
return placement;
}
if (distance_from_left > popover_width && elt_will_fit_vertically) {
placement = "left";
}
if (distance_from_right > popover_width && elt_will_fit_vertically) {
placement = "right";
}
return placement;
}
export function post_hotspot_as_read(hotspot_name) {
channel.post({
url: "/json/users/me/hotspots",
@ -124,12 +166,7 @@ function place_popover(hotspot) {
let arrow_placement;
const orientation =
hotspot.location.popover ||
popovers.compute_placement(
$(hotspot.location.element),
popover_height,
popover_width,
false,
);
compute_placement($(hotspot.location.element), popover_height, popover_width, false);
switch (orientation) {
case TOP:

View File

@ -3,7 +3,6 @@ import {hideAll} from "tippy.js";
import * as blueslip from "./blueslip";
import * as emoji_picker from "./emoji_picker";
import * as message_viewport from "./message_viewport";
import * as overlays from "./overlays";
import * as playground_links_popover from "./playground_links_popover";
import * as popover_menus from "./popover_menus";
@ -206,53 +205,6 @@ export function hide_all(not_hide_tippy_instances) {
});
}
export function compute_placement(
$elt,
popover_height,
popover_width,
prefer_vertical_positioning,
) {
const client_rect = $elt.get(0).getBoundingClientRect();
const distance_from_top = client_rect.top;
const distance_from_bottom = message_viewport.height() - client_rect.bottom;
const distance_from_left = client_rect.left;
const distance_from_right = message_viewport.width() - client_rect.right;
const elt_will_fit_horizontally =
distance_from_left + $elt.width() / 2 > popover_width / 2 &&
distance_from_right + $elt.width() / 2 > popover_width / 2;
const elt_will_fit_vertically =
distance_from_bottom + $elt.height() / 2 > popover_height / 2 &&
distance_from_top + $elt.height() / 2 > popover_height / 2;
// default to placing the popover in the center of the screen
let placement = "viewport_center";
// prioritize left/right over top/bottom
if (distance_from_top > popover_height && elt_will_fit_horizontally) {
placement = "top";
}
if (distance_from_bottom > popover_height && elt_will_fit_horizontally) {
placement = "bottom";
}
if (prefer_vertical_positioning && placement !== "viewport_center") {
// If vertical positioning is preferred and the popover fits in
// either top or bottom position then return.
return placement;
}
if (distance_from_left > popover_width && elt_will_fit_vertically) {
placement = "left";
}
if (distance_from_right > popover_width && elt_will_fit_vertically) {
placement = "right";
}
return placement;
}
export function initialize() {
overlays.register_pre_open_hook(hide_all);
overlays.register_pre_close_hook(hide_all);