zulip/web/src/resize.js

202 lines
7.6 KiB
JavaScript
Raw Normal View History

import autosize from "autosize";
import $ from "jquery";
import * as blueslip from "./blueslip";
import * as compose_state from "./compose_state";
import * as compose_ui from "./compose_ui";
import * as message_viewport from "./message_viewport";
function get_bottom_whitespace_height() {
return message_viewport.height() * 0.4;
}
function get_new_heights() {
const res = {};
const viewport_height = message_viewport.height();
const right_sidebar_shortcuts_height = $(".right-sidebar-shortcuts").outerHeight(true) ?? 0;
res.stream_filters_max_height =
viewport_height -
Number.parseInt($("#left-sidebar").css("paddingTop"), 10) -
Number.parseInt($("#left-sidebar-navigation-area").css("marginTop"), 10) -
Number.parseInt($("#left-sidebar-navigation-area").css("marginBottom"), 10) -
($("#left-sidebar-navigation-list").outerHeight(true) ?? 0) -
($("#private_messages_sticky_header").outerHeight(true) ?? 0);
// Don't let us crush the stream sidebar completely out of view
res.stream_filters_max_height = Math.max(80, res.stream_filters_max_height);
// RIGHT SIDEBAR
const usable_height =
viewport_height -
Number.parseInt($("#right-sidebar").css("paddingTop"), 10) -
($("#userlist-header").outerHeight(true) ?? 0) -
($("#user_search_section").outerHeight(true) ?? 0) -
right_sidebar_shortcuts_height;
res.buddy_list_wrapper_max_height = Math.max(80, usable_height);
return res;
}
export function watch_manual_resize(element) {
const box = document.querySelector(element);
if (!box) {
blueslip.error("Bad selector in watch_manual_resize", {element});
return undefined;
}
const meta = {
box,
height: null,
mousedown: false,
};
const box_handler = function () {
meta.mousedown = true;
meta.height = meta.box.clientHeight;
};
meta.box.addEventListener("mousedown", box_handler);
// If the user resizes the textarea manually, we use the
// callback to stop autosize from adjusting the height.
// It will be re-enabled when this component is next opened.
const body_handler = function () {
if (meta.mousedown === true) {
meta.mousedown = false;
if (meta.height !== meta.box.clientHeight) {
meta.height = meta.box.clientHeight;
autosize.destroy($(element)).height(meta.height + "px");
}
}
};
document.body.addEventListener("mouseup", body_handler);
return [box_handler, body_handler];
}
export function reset_compose_message_max_height(bottom_whitespace_height) {
compose-box: Fix compose-box from covering last messages of stream. While writing a long message in compose-box, the last few messages of the current stream gets covered by the compose-box and it gets pretty annoying sometimes trying to figure out a way to read the last message of the stream while writing. Right now, the only way to get past this is to resize `compose-textarea` by using the resize tool at the bottom-right corner of the `compose-textarea`. But, that small resize tool is not always readily visible to the user. The proposed solution in this commit is to reset the `max-height` property of `#compose-textarea` everytime `bottom_whitespace_height` is resized such that the total height of `#compose` is always less than or equal to the height of `bottom_whitespace_height`. Doing this, the compose-box never covers the last message of the current stream. The only problem with this is that if the compose-box is closed at the time of bottom-whitespace resize, we cannot find the `compose_non_textarea_height` and so, we cannot reset the max-height of `#compose-textarea`. To solve this, max-height of `compose-textarea` is also reset everytime a new compose-box is opened according to the value of `bottom_whitespace_height` at that time. Thus, if the compose-box is already open at the time of bottom-whitespace resize, the max-height of `#compose-textarea` will also get reset at the same time, whereas, if the compose-box is closed at the time of bottom-whitespace resize, the max-height of `#compose-textarea` won't get reset at that time, but it will surely get reset whenever the user will open the compose-box. Tested on my Ubuntu Development Environment on Chrome and Firefox browsers. Fixes: #16038.
2021-01-18 14:23:29 +01:00
// If the compose-box is open, we set the `max-height` property of
// `compose-textarea` and `preview-textarea`, so that the
// compose-box's maximum extent does not overlap the last message
// in the current stream. We also leave a tiny bit of space after
// the last message of the current stream.
compose-box: Fix compose-box from covering last messages of stream. While writing a long message in compose-box, the last few messages of the current stream gets covered by the compose-box and it gets pretty annoying sometimes trying to figure out a way to read the last message of the stream while writing. Right now, the only way to get past this is to resize `compose-textarea` by using the resize tool at the bottom-right corner of the `compose-textarea`. But, that small resize tool is not always readily visible to the user. The proposed solution in this commit is to reset the `max-height` property of `#compose-textarea` everytime `bottom_whitespace_height` is resized such that the total height of `#compose` is always less than or equal to the height of `bottom_whitespace_height`. Doing this, the compose-box never covers the last message of the current stream. The only problem with this is that if the compose-box is closed at the time of bottom-whitespace resize, we cannot find the `compose_non_textarea_height` and so, we cannot reset the max-height of `#compose-textarea`. To solve this, max-height of `compose-textarea` is also reset everytime a new compose-box is opened according to the value of `bottom_whitespace_height` at that time. Thus, if the compose-box is already open at the time of bottom-whitespace resize, the max-height of `#compose-textarea` will also get reset at the same time, whereas, if the compose-box is closed at the time of bottom-whitespace resize, the max-height of `#compose-textarea` won't get reset at that time, but it will surely get reset whenever the user will open the compose-box. Tested on my Ubuntu Development Environment on Chrome and Firefox browsers. Fixes: #16038.
2021-01-18 14:23:29 +01:00
// Compute bottom_whitespace_height if not provided by caller.
if (typeof bottom_whitespace_height !== "number") {
bottom_whitespace_height = get_bottom_whitespace_height();
compose-box: Fix compose-box from covering last messages of stream. While writing a long message in compose-box, the last few messages of the current stream gets covered by the compose-box and it gets pretty annoying sometimes trying to figure out a way to read the last message of the stream while writing. Right now, the only way to get past this is to resize `compose-textarea` by using the resize tool at the bottom-right corner of the `compose-textarea`. But, that small resize tool is not always readily visible to the user. The proposed solution in this commit is to reset the `max-height` property of `#compose-textarea` everytime `bottom_whitespace_height` is resized such that the total height of `#compose` is always less than or equal to the height of `bottom_whitespace_height`. Doing this, the compose-box never covers the last message of the current stream. The only problem with this is that if the compose-box is closed at the time of bottom-whitespace resize, we cannot find the `compose_non_textarea_height` and so, we cannot reset the max-height of `#compose-textarea`. To solve this, max-height of `compose-textarea` is also reset everytime a new compose-box is opened according to the value of `bottom_whitespace_height` at that time. Thus, if the compose-box is already open at the time of bottom-whitespace resize, the max-height of `#compose-textarea` will also get reset at the same time, whereas, if the compose-box is closed at the time of bottom-whitespace resize, the max-height of `#compose-textarea` won't get reset at that time, but it will surely get reset whenever the user will open the compose-box. Tested on my Ubuntu Development Environment on Chrome and Firefox browsers. Fixes: #16038.
2021-01-18 14:23:29 +01:00
}
const compose_height = $("#compose").get(0).getBoundingClientRect().height;
const compose_textarea_height = Math.max(
$("textarea#compose-textarea").get(0).getBoundingClientRect().height,
$("#preview_message_area").get(0).getBoundingClientRect().height,
);
compose-box: Fix compose-box from covering last messages of stream. While writing a long message in compose-box, the last few messages of the current stream gets covered by the compose-box and it gets pretty annoying sometimes trying to figure out a way to read the last message of the stream while writing. Right now, the only way to get past this is to resize `compose-textarea` by using the resize tool at the bottom-right corner of the `compose-textarea`. But, that small resize tool is not always readily visible to the user. The proposed solution in this commit is to reset the `max-height` property of `#compose-textarea` everytime `bottom_whitespace_height` is resized such that the total height of `#compose` is always less than or equal to the height of `bottom_whitespace_height`. Doing this, the compose-box never covers the last message of the current stream. The only problem with this is that if the compose-box is closed at the time of bottom-whitespace resize, we cannot find the `compose_non_textarea_height` and so, we cannot reset the max-height of `#compose-textarea`. To solve this, max-height of `compose-textarea` is also reset everytime a new compose-box is opened according to the value of `bottom_whitespace_height` at that time. Thus, if the compose-box is already open at the time of bottom-whitespace resize, the max-height of `#compose-textarea` will also get reset at the same time, whereas, if the compose-box is closed at the time of bottom-whitespace resize, the max-height of `#compose-textarea` won't get reset at that time, but it will surely get reset whenever the user will open the compose-box. Tested on my Ubuntu Development Environment on Chrome and Firefox browsers. Fixes: #16038.
2021-01-18 14:23:29 +01:00
const compose_non_textarea_height = compose_height - compose_textarea_height;
// We ensure that the last message is not overlapped by compose box.
$("textarea#compose-textarea").css(
"max-height",
// Because <textarea> max-height includes padding, we subtract
// 10 for the padding and 10 for the selected message border.
bottom_whitespace_height - compose_non_textarea_height - 20,
);
$("#preview_message_area").css(
compose-box: Fix compose-box from covering last messages of stream. While writing a long message in compose-box, the last few messages of the current stream gets covered by the compose-box and it gets pretty annoying sometimes trying to figure out a way to read the last message of the stream while writing. Right now, the only way to get past this is to resize `compose-textarea` by using the resize tool at the bottom-right corner of the `compose-textarea`. But, that small resize tool is not always readily visible to the user. The proposed solution in this commit is to reset the `max-height` property of `#compose-textarea` everytime `bottom_whitespace_height` is resized such that the total height of `#compose` is always less than or equal to the height of `bottom_whitespace_height`. Doing this, the compose-box never covers the last message of the current stream. The only problem with this is that if the compose-box is closed at the time of bottom-whitespace resize, we cannot find the `compose_non_textarea_height` and so, we cannot reset the max-height of `#compose-textarea`. To solve this, max-height of `compose-textarea` is also reset everytime a new compose-box is opened according to the value of `bottom_whitespace_height` at that time. Thus, if the compose-box is already open at the time of bottom-whitespace resize, the max-height of `#compose-textarea` will also get reset at the same time, whereas, if the compose-box is closed at the time of bottom-whitespace resize, the max-height of `#compose-textarea` won't get reset at that time, but it will surely get reset whenever the user will open the compose-box. Tested on my Ubuntu Development Environment on Chrome and Firefox browsers. Fixes: #16038.
2021-01-18 14:23:29 +01:00
"max-height",
// Because <div> max-height doesn't include padding, we only
// subtract 10 for the selected message border.
compose-box: Fix compose-box from covering last messages of stream. While writing a long message in compose-box, the last few messages of the current stream gets covered by the compose-box and it gets pretty annoying sometimes trying to figure out a way to read the last message of the stream while writing. Right now, the only way to get past this is to resize `compose-textarea` by using the resize tool at the bottom-right corner of the `compose-textarea`. But, that small resize tool is not always readily visible to the user. The proposed solution in this commit is to reset the `max-height` property of `#compose-textarea` everytime `bottom_whitespace_height` is resized such that the total height of `#compose` is always less than or equal to the height of `bottom_whitespace_height`. Doing this, the compose-box never covers the last message of the current stream. The only problem with this is that if the compose-box is closed at the time of bottom-whitespace resize, we cannot find the `compose_non_textarea_height` and so, we cannot reset the max-height of `#compose-textarea`. To solve this, max-height of `compose-textarea` is also reset everytime a new compose-box is opened according to the value of `bottom_whitespace_height` at that time. Thus, if the compose-box is already open at the time of bottom-whitespace resize, the max-height of `#compose-textarea` will also get reset at the same time, whereas, if the compose-box is closed at the time of bottom-whitespace resize, the max-height of `#compose-textarea` won't get reset at that time, but it will surely get reset whenever the user will open the compose-box. Tested on my Ubuntu Development Environment on Chrome and Firefox browsers. Fixes: #16038.
2021-01-18 14:23:29 +01:00
bottom_whitespace_height - compose_non_textarea_height - 10,
);
$("#scroll-to-bottom-button-container").css("bottom", compose_height);
compose-box: Fix compose-box from covering last messages of stream. While writing a long message in compose-box, the last few messages of the current stream gets covered by the compose-box and it gets pretty annoying sometimes trying to figure out a way to read the last message of the stream while writing. Right now, the only way to get past this is to resize `compose-textarea` by using the resize tool at the bottom-right corner of the `compose-textarea`. But, that small resize tool is not always readily visible to the user. The proposed solution in this commit is to reset the `max-height` property of `#compose-textarea` everytime `bottom_whitespace_height` is resized such that the total height of `#compose` is always less than or equal to the height of `bottom_whitespace_height`. Doing this, the compose-box never covers the last message of the current stream. The only problem with this is that if the compose-box is closed at the time of bottom-whitespace resize, we cannot find the `compose_non_textarea_height` and so, we cannot reset the max-height of `#compose-textarea`. To solve this, max-height of `compose-textarea` is also reset everytime a new compose-box is opened according to the value of `bottom_whitespace_height` at that time. Thus, if the compose-box is already open at the time of bottom-whitespace resize, the max-height of `#compose-textarea` will also get reset at the same time, whereas, if the compose-box is closed at the time of bottom-whitespace resize, the max-height of `#compose-textarea` won't get reset at that time, but it will surely get reset whenever the user will open the compose-box. Tested on my Ubuntu Development Environment on Chrome and Firefox browsers. Fixes: #16038.
2021-01-18 14:23:29 +01:00
}
export function resize_bottom_whitespace() {
const bottom_whitespace_height = get_bottom_whitespace_height();
$("html").css("--max-unexpanded-compose-height", `${bottom_whitespace_height}px`);
compose-box: Fix compose-box from covering last messages of stream. While writing a long message in compose-box, the last few messages of the current stream gets covered by the compose-box and it gets pretty annoying sometimes trying to figure out a way to read the last message of the stream while writing. Right now, the only way to get past this is to resize `compose-textarea` by using the resize tool at the bottom-right corner of the `compose-textarea`. But, that small resize tool is not always readily visible to the user. The proposed solution in this commit is to reset the `max-height` property of `#compose-textarea` everytime `bottom_whitespace_height` is resized such that the total height of `#compose` is always less than or equal to the height of `bottom_whitespace_height`. Doing this, the compose-box never covers the last message of the current stream. The only problem with this is that if the compose-box is closed at the time of bottom-whitespace resize, we cannot find the `compose_non_textarea_height` and so, we cannot reset the max-height of `#compose-textarea`. To solve this, max-height of `compose-textarea` is also reset everytime a new compose-box is opened according to the value of `bottom_whitespace_height` at that time. Thus, if the compose-box is already open at the time of bottom-whitespace resize, the max-height of `#compose-textarea` will also get reset at the same time, whereas, if the compose-box is closed at the time of bottom-whitespace resize, the max-height of `#compose-textarea` won't get reset at that time, but it will surely get reset whenever the user will open the compose-box. Tested on my Ubuntu Development Environment on Chrome and Firefox browsers. Fixes: #16038.
2021-01-18 14:23:29 +01:00
// The height of the compose box is tied to that of
// bottom_whitespace, so update it if necessary.
//
// reset_compose_message_max_height cannot compute the right
compose-box: Fix compose-box from covering last messages of stream. While writing a long message in compose-box, the last few messages of the current stream gets covered by the compose-box and it gets pretty annoying sometimes trying to figure out a way to read the last message of the stream while writing. Right now, the only way to get past this is to resize `compose-textarea` by using the resize tool at the bottom-right corner of the `compose-textarea`. But, that small resize tool is not always readily visible to the user. The proposed solution in this commit is to reset the `max-height` property of `#compose-textarea` everytime `bottom_whitespace_height` is resized such that the total height of `#compose` is always less than or equal to the height of `bottom_whitespace_height`. Doing this, the compose-box never covers the last message of the current stream. The only problem with this is that if the compose-box is closed at the time of bottom-whitespace resize, we cannot find the `compose_non_textarea_height` and so, we cannot reset the max-height of `#compose-textarea`. To solve this, max-height of `compose-textarea` is also reset everytime a new compose-box is opened according to the value of `bottom_whitespace_height` at that time. Thus, if the compose-box is already open at the time of bottom-whitespace resize, the max-height of `#compose-textarea` will also get reset at the same time, whereas, if the compose-box is closed at the time of bottom-whitespace resize, the max-height of `#compose-textarea` won't get reset at that time, but it will surely get reset whenever the user will open the compose-box. Tested on my Ubuntu Development Environment on Chrome and Firefox browsers. Fixes: #16038.
2021-01-18 14:23:29 +01:00
// height correctly while compose is hidden. This is OK, because
// we also resize compose every time it is opened.
if (compose_state.composing()) {
reset_compose_message_max_height(bottom_whitespace_height);
compose-box: Fix compose-box from covering last messages of stream. While writing a long message in compose-box, the last few messages of the current stream gets covered by the compose-box and it gets pretty annoying sometimes trying to figure out a way to read the last message of the stream while writing. Right now, the only way to get past this is to resize `compose-textarea` by using the resize tool at the bottom-right corner of the `compose-textarea`. But, that small resize tool is not always readily visible to the user. The proposed solution in this commit is to reset the `max-height` property of `#compose-textarea` everytime `bottom_whitespace_height` is resized such that the total height of `#compose` is always less than or equal to the height of `bottom_whitespace_height`. Doing this, the compose-box never covers the last message of the current stream. The only problem with this is that if the compose-box is closed at the time of bottom-whitespace resize, we cannot find the `compose_non_textarea_height` and so, we cannot reset the max-height of `#compose-textarea`. To solve this, max-height of `compose-textarea` is also reset everytime a new compose-box is opened according to the value of `bottom_whitespace_height` at that time. Thus, if the compose-box is already open at the time of bottom-whitespace resize, the max-height of `#compose-textarea` will also get reset at the same time, whereas, if the compose-box is closed at the time of bottom-whitespace resize, the max-height of `#compose-textarea` won't get reset at that time, but it will surely get reset whenever the user will open the compose-box. Tested on my Ubuntu Development Environment on Chrome and Firefox browsers. Fixes: #16038.
2021-01-18 14:23:29 +01:00
}
}
export function resize_stream_subscribers_list() {
// Calculates the height of the subscribers list in stream settings.
// This avoids the stream settings from overflowing the container and
// having a scroll bar.
if (!$("#stream_settings").length === 1) {
// Don't run if stream settings (like $subscriptions_info below) is not open.
return;
}
const $subscriptions_info = $("#subscription_overlay .subscriptions-container .right");
const classes_above_subscribers_list = [
".display-type", // = stream_settings_title
".subscriber_list_settings_container .stream_settings_header",
".subscription_settings .stream_setting_subsection_title",
".subscription_settings .subscriber_list_settings",
".subscription_settings .stream_setting_subsection_title",
];
const $classes_above_subscribers_list = $subscriptions_info.find(
classes_above_subscribers_list.join(", "),
);
let total_height_of_classes_above_subscribers_list = 0;
$classes_above_subscribers_list.each(function () {
total_height_of_classes_above_subscribers_list += $(this).outerHeight(true);
});
const subscribers_list_header_height = 30;
const margin_between_tab_switcher_and_add_subscribers_title = 20;
const subscribers_list_height =
$subscriptions_info.height() -
total_height_of_classes_above_subscribers_list -
subscribers_list_header_height -
margin_between_tab_switcher_and_add_subscribers_title;
$("html").css("--stream-subscriber-list-max-height", `${subscribers_list_height}px`);
}
2022-11-10 12:30:38 +01:00
export function resize_stream_filters_container() {
const h = get_new_heights();
resize_bottom_whitespace();
$("#left_sidebar_scroll_container").css("max-height", h.stream_filters_max_height);
}
export function resize_sidebars() {
const h = get_new_heights();
$("#buddy_list_wrapper").css("max-height", h.buddy_list_wrapper_max_height);
$("#left_sidebar_scroll_container").css("max-height", h.stream_filters_max_height);
return h;
}
export function update_recent_view_filters_height() {
const recent_view_filters_height = $("#recent_view_filter_buttons").outerHeight(true) ?? 0;
$("html").css("--recent-topics-filters-height", `${recent_view_filters_height}px`);
}
function resize_navbar_alerts() {
const navbar_alerts_height = $("#navbar_alerts_wrapper").height();
document.documentElement.style.setProperty(
"--navbar-alerts-wrapper-height",
navbar_alerts_height + "px",
);
// If the compose-box is in expanded state,
// reset its height as well.
if (compose_ui.is_full_size()) {
compose_ui.set_compose_box_top(true);
}
}
export function resize_page_components() {
resize_navbar_alerts();
const h = resize_sidebars();
resize_bottom_whitespace(h);
resize_stream_subscribers_list();
}