mirror of
https://github.com/zulip/zulip.git
synced 2025-11-04 14:03:30 +00:00
viewports: Re-engineer breakpoint detection from JavaScript.
This commit is contained in:
@@ -12,7 +12,6 @@ import render_presence_rows from "../templates/presence_rows.hbs";
|
|||||||
import * as blueslip from "./blueslip.ts";
|
import * as blueslip from "./blueslip.ts";
|
||||||
import * as buddy_data from "./buddy_data.ts";
|
import * as buddy_data from "./buddy_data.ts";
|
||||||
import type {BuddyUserInfo} from "./buddy_data.ts";
|
import type {BuddyUserInfo} from "./buddy_data.ts";
|
||||||
import {media_breakpoints_num} from "./css_variables.ts";
|
|
||||||
import type {Filter} from "./filter.ts";
|
import type {Filter} from "./filter.ts";
|
||||||
import * as hash_util from "./hash_util.ts";
|
import * as hash_util from "./hash_util.ts";
|
||||||
import {$t} from "./i18n.ts";
|
import {$t} from "./i18n.ts";
|
||||||
@@ -26,6 +25,7 @@ import {current_user} from "./state_data.ts";
|
|||||||
import * as stream_data from "./stream_data.ts";
|
import * as stream_data from "./stream_data.ts";
|
||||||
import type {StreamSubscription} from "./sub_store.ts";
|
import type {StreamSubscription} from "./sub_store.ts";
|
||||||
import {INTERACTIVE_HOVER_DELAY} from "./tippyjs.ts";
|
import {INTERACTIVE_HOVER_DELAY} from "./tippyjs.ts";
|
||||||
|
import * as ui_util from "./ui_util.ts";
|
||||||
import {user_settings} from "./user_settings.ts";
|
import {user_settings} from "./user_settings.ts";
|
||||||
import * as util from "./util.ts";
|
import * as util from "./util.ts";
|
||||||
|
|
||||||
@@ -174,7 +174,7 @@ export class BuddyList extends BuddyListConf {
|
|||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
const $elem = $(this);
|
const $elem = $(this);
|
||||||
let placement: "left" | "auto" = "left";
|
let placement: "left" | "auto" = "left";
|
||||||
if (window.innerWidth < media_breakpoints_num.md) {
|
if (ui_util.matches_viewport_state("lt_md_min")) {
|
||||||
// On small devices display tooltips based on available space.
|
// On small devices display tooltips based on available space.
|
||||||
// This will default to "bottom" placement for this tooltip.
|
// This will default to "bottom" placement for this tooltip.
|
||||||
placement = "auto";
|
placement = "auto";
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ import * as buddy_data from "./buddy_data.ts";
|
|||||||
import * as compose_actions from "./compose_actions.ts";
|
import * as compose_actions from "./compose_actions.ts";
|
||||||
import * as compose_reply from "./compose_reply.ts";
|
import * as compose_reply from "./compose_reply.ts";
|
||||||
import * as compose_state from "./compose_state.ts";
|
import * as compose_state from "./compose_state.ts";
|
||||||
import {media_breakpoints_num} from "./css_variables.ts";
|
|
||||||
import * as emoji_picker from "./emoji_picker.ts";
|
import * as emoji_picker from "./emoji_picker.ts";
|
||||||
import * as hash_util from "./hash_util.ts";
|
import * as hash_util from "./hash_util.ts";
|
||||||
import * as hashchange from "./hashchange.ts";
|
import * as hashchange from "./hashchange.ts";
|
||||||
@@ -484,7 +483,7 @@ export function initialize(): void {
|
|||||||
): void {
|
): void {
|
||||||
let placement: tippy.Placement = "left";
|
let placement: tippy.Placement = "left";
|
||||||
let observer: MutationObserver;
|
let observer: MutationObserver;
|
||||||
if (window.innerWidth < media_breakpoints_num.md) {
|
if (ui_util.matches_viewport_state("lt_md_min")) {
|
||||||
// On small devices display tooltips based on available space.
|
// On small devices display tooltips based on available space.
|
||||||
// This will default to "bottom" placement for this tooltip.
|
// This will default to "bottom" placement for this tooltip.
|
||||||
placement = "auto";
|
placement = "auto";
|
||||||
|
|||||||
@@ -6,11 +6,11 @@ import $ from "jquery";
|
|||||||
import * as tippy from "tippy.js";
|
import * as tippy from "tippy.js";
|
||||||
|
|
||||||
import * as blueslip from "./blueslip.ts";
|
import * as blueslip from "./blueslip.ts";
|
||||||
import {media_breakpoints_num} from "./css_variables.ts";
|
|
||||||
import * as message_viewport from "./message_viewport.ts";
|
import * as message_viewport from "./message_viewport.ts";
|
||||||
import * as modals from "./modals.ts";
|
import * as modals from "./modals.ts";
|
||||||
import * as overlays from "./overlays.ts";
|
import * as overlays from "./overlays.ts";
|
||||||
import * as popovers from "./popovers.ts";
|
import * as popovers from "./popovers.ts";
|
||||||
|
import * as ui_util from "./ui_util.ts";
|
||||||
import * as util from "./util.ts";
|
import * as util from "./util.ts";
|
||||||
|
|
||||||
type PopoverName =
|
type PopoverName =
|
||||||
@@ -418,7 +418,7 @@ export function toggle_popover_menu(
|
|||||||
// popover centered on the screen as an overlay.
|
// popover centered on the screen as an overlay.
|
||||||
let show_as_overlay =
|
let show_as_overlay =
|
||||||
(options?.show_as_overlay_on_mobile === true &&
|
(options?.show_as_overlay_on_mobile === true &&
|
||||||
window.innerWidth <= media_breakpoints_num.md) ||
|
ui_util.matches_viewport_state("lt_md_min")) ||
|
||||||
options?.show_as_overlay_always === true;
|
options?.show_as_overlay_always === true;
|
||||||
// Show the popover as over if the reference element is hidden.
|
// Show the popover as over if the reference element is hidden.
|
||||||
if (!show_as_overlay && options?.show_as_overlay_if_reference_hidden_at_trigger) {
|
if (!show_as_overlay && options?.show_as_overlay_if_reference_hidden_at_trigger) {
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ import render_right_sidebar from "../templates/right_sidebar.hbs";
|
|||||||
import {buddy_list} from "./buddy_list.ts";
|
import {buddy_list} from "./buddy_list.ts";
|
||||||
import * as channel from "./channel.ts";
|
import * as channel from "./channel.ts";
|
||||||
import * as compose_ui from "./compose_ui.ts";
|
import * as compose_ui from "./compose_ui.ts";
|
||||||
import {media_breakpoints_num} from "./css_variables.ts";
|
|
||||||
import {reorder_left_sidebar_navigation_list} from "./left_sidebar_navigation_area.ts";
|
import {reorder_left_sidebar_navigation_list} from "./left_sidebar_navigation_area.ts";
|
||||||
import {localstorage} from "./localstorage.ts";
|
import {localstorage} from "./localstorage.ts";
|
||||||
import * as message_lists from "./message_lists.ts";
|
import * as message_lists from "./message_lists.ts";
|
||||||
@@ -56,7 +55,7 @@ export function show_userlist_sidebar(): void {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (window.innerWidth >= media_breakpoints_num.xl) {
|
if (ui_util.matches_viewport_state("gte_xl_min")) {
|
||||||
$("body").removeClass("hide-right-sidebar");
|
$("body").removeClass("hide-right-sidebar");
|
||||||
fix_invite_user_button_flicker();
|
fix_invite_user_button_flicker();
|
||||||
return;
|
return;
|
||||||
@@ -146,7 +145,7 @@ export function initialize(): void {
|
|||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
|
|
||||||
if (window.innerWidth >= media_breakpoints_num.xl) {
|
if (ui_util.matches_viewport_state("gte_xl_min")) {
|
||||||
$("body").toggleClass("hide-right-sidebar");
|
$("body").toggleClass("hide-right-sidebar");
|
||||||
if (!$("body").hasClass("hide-right-sidebar")) {
|
if (!$("body").hasClass("hide-right-sidebar")) {
|
||||||
fix_invite_user_button_flicker();
|
fix_invite_user_button_flicker();
|
||||||
@@ -172,11 +171,11 @@ export function initialize(): void {
|
|||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
|
|
||||||
if (window.innerWidth >= media_breakpoints_num.md) {
|
if (ui_util.matches_viewport_state("gte_md_min")) {
|
||||||
$("body").toggleClass("hide-left-sidebar");
|
$("body").toggleClass("hide-left-sidebar");
|
||||||
if (
|
if (
|
||||||
message_lists.current !== undefined &&
|
message_lists.current !== undefined &&
|
||||||
window.innerWidth <= media_breakpoints_num.xl
|
!ui_util.matches_viewport_state("gte_xl_min")
|
||||||
) {
|
) {
|
||||||
// We expand the middle column width between md and xl breakpoints when the
|
// We expand the middle column width between md and xl breakpoints when the
|
||||||
// left sidebar is hidden. This can cause the pointer to move out of view.
|
// left sidebar is hidden. This can cause the pointer to move out of view.
|
||||||
|
|||||||
@@ -258,3 +258,16 @@ export function show_left_sidebar_menu_icon(element: Element): void {
|
|||||||
export function hide_left_sidebar_menu_icon(): void {
|
export function hide_left_sidebar_menu_icon(): void {
|
||||||
$(".left_sidebar_menu_icon_visible").removeClass("left_sidebar_menu_icon_visible");
|
$(".left_sidebar_menu_icon_visible").removeClass("left_sidebar_menu_icon_visible");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function matches_viewport_state(state_string: string): boolean {
|
||||||
|
const app_main = document.querySelector(".app-main");
|
||||||
|
if (app_main instanceof HTMLElement) {
|
||||||
|
const app_main_after_content = getComputedStyle(app_main, ":after").content ?? "";
|
||||||
|
/* The .content property includes the quotation marks, so we
|
||||||
|
strip them before splitting on the empty space. */
|
||||||
|
const app_main_after_content_array = app_main_after_content.replaceAll('"', "").split(" ");
|
||||||
|
|
||||||
|
return app_main_after_content_array.includes(state_string);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|||||||
@@ -495,6 +495,15 @@ body.has-overlay-scrollbar {
|
|||||||
height: 100%;
|
height: 100%;
|
||||||
min-height: 100%;
|
min-height: 100%;
|
||||||
|
|
||||||
|
&::after {
|
||||||
|
/* We use `content` values to determine
|
||||||
|
viewport state from JavaScript; this
|
||||||
|
hides the values without disrupting
|
||||||
|
the document flow. */
|
||||||
|
position: absolute;
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
.column-left .left-sidebar,
|
.column-left .left-sidebar,
|
||||||
.column-right .right-sidebar {
|
.column-right .right-sidebar {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
@@ -1861,6 +1870,55 @@ body:not(.hide-left-sidebar) {
|
|||||||
|
|
||||||
/* End fallback media queries. */
|
/* End fallback media queries. */
|
||||||
|
|
||||||
|
/* Begin viewport state queries. */
|
||||||
|
|
||||||
|
/* We sometimes need the state of the viewport in JavaScript;
|
||||||
|
by setting values on `content:`, we can query instead for
|
||||||
|
those, independent of whether it's a container or media query
|
||||||
|
responsible for layout. See for example `sidebar_ui.ts`.
|
||||||
|
|
||||||
|
These queries for greater than or equal to should be ordered
|
||||||
|
smallest to largest. */
|
||||||
|
|
||||||
|
/* Adjustments for smaller viewports are critical
|
||||||
|
regardless of info-density settings, so we
|
||||||
|
don't include a container-query check here. */
|
||||||
|
@media (width < $md_min) {
|
||||||
|
.app-main::after {
|
||||||
|
content: "lt_md_min";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@container app (width >= $cq_md_min) {
|
||||||
|
.app-main::after {
|
||||||
|
content: "gte_md_min";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (width >= $md_min) {
|
||||||
|
.without-container-query-support {
|
||||||
|
.app-main::after {
|
||||||
|
content: "gte_md_min";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@container app (width >= $cq_xl_min) {
|
||||||
|
.app-main::after {
|
||||||
|
content: "gte_md_min gte_xl_min";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (width >= $xl_min) {
|
||||||
|
.without-container-query-support {
|
||||||
|
.app-main::after {
|
||||||
|
content: "gte_md_min gte_xl_min";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* End viewport state queries. */
|
||||||
|
|
||||||
@media (height < $short_navbar_cutoff_height) {
|
@media (height < $short_navbar_cutoff_height) {
|
||||||
.app-main .column-right.expanded .right-sidebar,
|
.app-main .column-right.expanded .right-sidebar,
|
||||||
.app-main .column-left.expanded .left-sidebar {
|
.app-main .column-left.expanded .left-sidebar {
|
||||||
|
|||||||
Reference in New Issue
Block a user