2020-02-13 22:34:29 +01:00
|
|
|
const util = require("./util");
|
2019-11-02 00:06:25 +01:00
|
|
|
const autosize = require('autosize');
|
2019-07-16 20:19:11 +02:00
|
|
|
|
2019-11-02 00:06:25 +01:00
|
|
|
let narrow_window = false;
|
2014-03-13 19:03:31 +01:00
|
|
|
|
|
|
|
function confine_to_range(lo, val, hi) {
|
|
|
|
if (val < lo) {
|
|
|
|
return lo;
|
|
|
|
}
|
|
|
|
if (val > hi) {
|
|
|
|
return hi;
|
|
|
|
}
|
|
|
|
return val;
|
|
|
|
}
|
|
|
|
|
|
|
|
function size_blocks(blocks, usable_height) {
|
2019-11-02 00:06:25 +01:00
|
|
|
let sum_height = 0;
|
js: Automatically convert _.each to for…of.
This commit was automatically generated by the following script,
followed by lint --fix and a few small manual lint-related cleanups.
import * as babelParser from "recast/parsers/babel";
import * as recast from "recast";
import * as tsParser from "recast/parsers/typescript";
import { builders as b, namedTypes as n } from "ast-types";
import { Context } from "ast-types/lib/path-visitor";
import K from "ast-types/gen/kinds";
import { NodePath } from "ast-types/lib/node-path";
import assert from "assert";
import fs from "fs";
import path from "path";
import process from "process";
const checkExpression = (node: n.Node): node is K.ExpressionKind =>
n.Expression.check(node);
const checkStatement = (node: n.Node): node is K.StatementKind =>
n.Statement.check(node);
for (const file of process.argv.slice(2)) {
console.log("Parsing", file);
const ast = recast.parse(fs.readFileSync(file, { encoding: "utf8" }), {
parser: path.extname(file) === ".ts" ? tsParser : babelParser,
});
let changed = false;
let inLoop = false;
let replaceReturn = false;
const visitLoop = (...args: string[]) =>
function(this: Context, path: NodePath) {
for (const arg of args) {
this.visit(path.get(arg));
}
const old = { inLoop };
inLoop = true;
this.visit(path.get("body"));
inLoop = old.inLoop;
return false;
};
recast.visit(ast, {
visitDoWhileStatement: visitLoop("test"),
visitExpressionStatement(path) {
const { expression, comments } = path.node;
let valueOnly;
if (
n.CallExpression.check(expression) &&
n.MemberExpression.check(expression.callee) &&
!expression.callee.computed &&
n.Identifier.check(expression.callee.object) &&
expression.callee.object.name === "_" &&
n.Identifier.check(expression.callee.property) &&
["each", "forEach"].includes(expression.callee.property.name) &&
[2, 3].includes(expression.arguments.length) &&
checkExpression(expression.arguments[0]) &&
(n.FunctionExpression.check(expression.arguments[1]) ||
n.ArrowFunctionExpression.check(expression.arguments[1])) &&
[1, 2].includes(expression.arguments[1].params.length) &&
n.Identifier.check(expression.arguments[1].params[0]) &&
((valueOnly = expression.arguments[1].params[1] === undefined) ||
n.Identifier.check(expression.arguments[1].params[1])) &&
(expression.arguments[2] === undefined ||
n.ThisExpression.check(expression.arguments[2]))
) {
const old = { inLoop, replaceReturn };
inLoop = false;
replaceReturn = true;
this.visit(
path
.get("expression")
.get("arguments")
.get(1)
.get("body")
);
inLoop = old.inLoop;
replaceReturn = old.replaceReturn;
const [right, { body, params }] = expression.arguments;
const loop = b.forOfStatement(
b.variableDeclaration("let", [
b.variableDeclarator(
valueOnly ? params[0] : b.arrayPattern([params[1], params[0]])
),
]),
valueOnly
? right
: b.callExpression(
b.memberExpression(right, b.identifier("entries")),
[]
),
checkStatement(body) ? body : b.expressionStatement(body)
);
loop.comments = comments;
path.replace(loop);
changed = true;
}
this.traverse(path);
},
visitForStatement: visitLoop("init", "test", "update"),
visitForInStatement: visitLoop("left", "right"),
visitForOfStatement: visitLoop("left", "right"),
visitFunction(path) {
this.visit(path.get("params"));
const old = { replaceReturn };
replaceReturn = false;
this.visit(path.get("body"));
replaceReturn = old.replaceReturn;
return false;
},
visitReturnStatement(path) {
if (replaceReturn) {
assert(!inLoop); // could use labeled continue if this ever fires
const { argument, comments } = path.node;
if (argument === null) {
const s = b.continueStatement();
s.comments = comments;
path.replace(s);
} else {
const s = b.expressionStatement(argument);
s.comments = comments;
path.replace(s, b.continueStatement());
}
return false;
}
this.traverse(path);
},
visitWhileStatement: visitLoop("test"),
});
if (changed) {
console.log("Writing", file);
fs.writeFileSync(file, recast.print(ast).code, { encoding: "utf8" });
}
}
Signed-off-by: Anders Kaseorg <anders@zulipchat.com>
2020-02-06 06:19:47 +01:00
|
|
|
|
|
|
|
for (const block of blocks) {
|
2014-03-13 19:03:31 +01:00
|
|
|
sum_height += block.real_height;
|
js: Automatically convert _.each to for…of.
This commit was automatically generated by the following script,
followed by lint --fix and a few small manual lint-related cleanups.
import * as babelParser from "recast/parsers/babel";
import * as recast from "recast";
import * as tsParser from "recast/parsers/typescript";
import { builders as b, namedTypes as n } from "ast-types";
import { Context } from "ast-types/lib/path-visitor";
import K from "ast-types/gen/kinds";
import { NodePath } from "ast-types/lib/node-path";
import assert from "assert";
import fs from "fs";
import path from "path";
import process from "process";
const checkExpression = (node: n.Node): node is K.ExpressionKind =>
n.Expression.check(node);
const checkStatement = (node: n.Node): node is K.StatementKind =>
n.Statement.check(node);
for (const file of process.argv.slice(2)) {
console.log("Parsing", file);
const ast = recast.parse(fs.readFileSync(file, { encoding: "utf8" }), {
parser: path.extname(file) === ".ts" ? tsParser : babelParser,
});
let changed = false;
let inLoop = false;
let replaceReturn = false;
const visitLoop = (...args: string[]) =>
function(this: Context, path: NodePath) {
for (const arg of args) {
this.visit(path.get(arg));
}
const old = { inLoop };
inLoop = true;
this.visit(path.get("body"));
inLoop = old.inLoop;
return false;
};
recast.visit(ast, {
visitDoWhileStatement: visitLoop("test"),
visitExpressionStatement(path) {
const { expression, comments } = path.node;
let valueOnly;
if (
n.CallExpression.check(expression) &&
n.MemberExpression.check(expression.callee) &&
!expression.callee.computed &&
n.Identifier.check(expression.callee.object) &&
expression.callee.object.name === "_" &&
n.Identifier.check(expression.callee.property) &&
["each", "forEach"].includes(expression.callee.property.name) &&
[2, 3].includes(expression.arguments.length) &&
checkExpression(expression.arguments[0]) &&
(n.FunctionExpression.check(expression.arguments[1]) ||
n.ArrowFunctionExpression.check(expression.arguments[1])) &&
[1, 2].includes(expression.arguments[1].params.length) &&
n.Identifier.check(expression.arguments[1].params[0]) &&
((valueOnly = expression.arguments[1].params[1] === undefined) ||
n.Identifier.check(expression.arguments[1].params[1])) &&
(expression.arguments[2] === undefined ||
n.ThisExpression.check(expression.arguments[2]))
) {
const old = { inLoop, replaceReturn };
inLoop = false;
replaceReturn = true;
this.visit(
path
.get("expression")
.get("arguments")
.get(1)
.get("body")
);
inLoop = old.inLoop;
replaceReturn = old.replaceReturn;
const [right, { body, params }] = expression.arguments;
const loop = b.forOfStatement(
b.variableDeclaration("let", [
b.variableDeclarator(
valueOnly ? params[0] : b.arrayPattern([params[1], params[0]])
),
]),
valueOnly
? right
: b.callExpression(
b.memberExpression(right, b.identifier("entries")),
[]
),
checkStatement(body) ? body : b.expressionStatement(body)
);
loop.comments = comments;
path.replace(loop);
changed = true;
}
this.traverse(path);
},
visitForStatement: visitLoop("init", "test", "update"),
visitForInStatement: visitLoop("left", "right"),
visitForOfStatement: visitLoop("left", "right"),
visitFunction(path) {
this.visit(path.get("params"));
const old = { replaceReturn };
replaceReturn = false;
this.visit(path.get("body"));
replaceReturn = old.replaceReturn;
return false;
},
visitReturnStatement(path) {
if (replaceReturn) {
assert(!inLoop); // could use labeled continue if this ever fires
const { argument, comments } = path.node;
if (argument === null) {
const s = b.continueStatement();
s.comments = comments;
path.replace(s);
} else {
const s = b.expressionStatement(argument);
s.comments = comments;
path.replace(s, b.continueStatement());
}
return false;
}
this.traverse(path);
},
visitWhileStatement: visitLoop("test"),
});
if (changed) {
console.log("Writing", file);
fs.writeFileSync(file, recast.print(ast).code, { encoding: "utf8" });
}
}
Signed-off-by: Anders Kaseorg <anders@zulipchat.com>
2020-02-06 06:19:47 +01:00
|
|
|
}
|
2014-03-13 19:03:31 +01:00
|
|
|
|
js: Automatically convert _.each to for…of.
This commit was automatically generated by the following script,
followed by lint --fix and a few small manual lint-related cleanups.
import * as babelParser from "recast/parsers/babel";
import * as recast from "recast";
import * as tsParser from "recast/parsers/typescript";
import { builders as b, namedTypes as n } from "ast-types";
import { Context } from "ast-types/lib/path-visitor";
import K from "ast-types/gen/kinds";
import { NodePath } from "ast-types/lib/node-path";
import assert from "assert";
import fs from "fs";
import path from "path";
import process from "process";
const checkExpression = (node: n.Node): node is K.ExpressionKind =>
n.Expression.check(node);
const checkStatement = (node: n.Node): node is K.StatementKind =>
n.Statement.check(node);
for (const file of process.argv.slice(2)) {
console.log("Parsing", file);
const ast = recast.parse(fs.readFileSync(file, { encoding: "utf8" }), {
parser: path.extname(file) === ".ts" ? tsParser : babelParser,
});
let changed = false;
let inLoop = false;
let replaceReturn = false;
const visitLoop = (...args: string[]) =>
function(this: Context, path: NodePath) {
for (const arg of args) {
this.visit(path.get(arg));
}
const old = { inLoop };
inLoop = true;
this.visit(path.get("body"));
inLoop = old.inLoop;
return false;
};
recast.visit(ast, {
visitDoWhileStatement: visitLoop("test"),
visitExpressionStatement(path) {
const { expression, comments } = path.node;
let valueOnly;
if (
n.CallExpression.check(expression) &&
n.MemberExpression.check(expression.callee) &&
!expression.callee.computed &&
n.Identifier.check(expression.callee.object) &&
expression.callee.object.name === "_" &&
n.Identifier.check(expression.callee.property) &&
["each", "forEach"].includes(expression.callee.property.name) &&
[2, 3].includes(expression.arguments.length) &&
checkExpression(expression.arguments[0]) &&
(n.FunctionExpression.check(expression.arguments[1]) ||
n.ArrowFunctionExpression.check(expression.arguments[1])) &&
[1, 2].includes(expression.arguments[1].params.length) &&
n.Identifier.check(expression.arguments[1].params[0]) &&
((valueOnly = expression.arguments[1].params[1] === undefined) ||
n.Identifier.check(expression.arguments[1].params[1])) &&
(expression.arguments[2] === undefined ||
n.ThisExpression.check(expression.arguments[2]))
) {
const old = { inLoop, replaceReturn };
inLoop = false;
replaceReturn = true;
this.visit(
path
.get("expression")
.get("arguments")
.get(1)
.get("body")
);
inLoop = old.inLoop;
replaceReturn = old.replaceReturn;
const [right, { body, params }] = expression.arguments;
const loop = b.forOfStatement(
b.variableDeclaration("let", [
b.variableDeclarator(
valueOnly ? params[0] : b.arrayPattern([params[1], params[0]])
),
]),
valueOnly
? right
: b.callExpression(
b.memberExpression(right, b.identifier("entries")),
[]
),
checkStatement(body) ? body : b.expressionStatement(body)
);
loop.comments = comments;
path.replace(loop);
changed = true;
}
this.traverse(path);
},
visitForStatement: visitLoop("init", "test", "update"),
visitForInStatement: visitLoop("left", "right"),
visitForOfStatement: visitLoop("left", "right"),
visitFunction(path) {
this.visit(path.get("params"));
const old = { replaceReturn };
replaceReturn = false;
this.visit(path.get("body"));
replaceReturn = old.replaceReturn;
return false;
},
visitReturnStatement(path) {
if (replaceReturn) {
assert(!inLoop); // could use labeled continue if this ever fires
const { argument, comments } = path.node;
if (argument === null) {
const s = b.continueStatement();
s.comments = comments;
path.replace(s);
} else {
const s = b.expressionStatement(argument);
s.comments = comments;
path.replace(s, b.continueStatement());
}
return false;
}
this.traverse(path);
},
visitWhileStatement: visitLoop("test"),
});
if (changed) {
console.log("Writing", file);
fs.writeFileSync(file, recast.print(ast).code, { encoding: "utf8" });
}
}
Signed-off-by: Anders Kaseorg <anders@zulipchat.com>
2020-02-06 06:19:47 +01:00
|
|
|
for (const block of blocks) {
|
2019-11-02 00:06:25 +01:00
|
|
|
let ratio = block.real_height / sum_height;
|
2014-03-13 19:03:31 +01:00
|
|
|
ratio = confine_to_range(0.05, ratio, 0.85);
|
2017-01-09 11:38:38 +01:00
|
|
|
block.max_height = confine_to_range(80, usable_height * ratio, 1.2 * block.real_height);
|
js: Automatically convert _.each to for…of.
This commit was automatically generated by the following script,
followed by lint --fix and a few small manual lint-related cleanups.
import * as babelParser from "recast/parsers/babel";
import * as recast from "recast";
import * as tsParser from "recast/parsers/typescript";
import { builders as b, namedTypes as n } from "ast-types";
import { Context } from "ast-types/lib/path-visitor";
import K from "ast-types/gen/kinds";
import { NodePath } from "ast-types/lib/node-path";
import assert from "assert";
import fs from "fs";
import path from "path";
import process from "process";
const checkExpression = (node: n.Node): node is K.ExpressionKind =>
n.Expression.check(node);
const checkStatement = (node: n.Node): node is K.StatementKind =>
n.Statement.check(node);
for (const file of process.argv.slice(2)) {
console.log("Parsing", file);
const ast = recast.parse(fs.readFileSync(file, { encoding: "utf8" }), {
parser: path.extname(file) === ".ts" ? tsParser : babelParser,
});
let changed = false;
let inLoop = false;
let replaceReturn = false;
const visitLoop = (...args: string[]) =>
function(this: Context, path: NodePath) {
for (const arg of args) {
this.visit(path.get(arg));
}
const old = { inLoop };
inLoop = true;
this.visit(path.get("body"));
inLoop = old.inLoop;
return false;
};
recast.visit(ast, {
visitDoWhileStatement: visitLoop("test"),
visitExpressionStatement(path) {
const { expression, comments } = path.node;
let valueOnly;
if (
n.CallExpression.check(expression) &&
n.MemberExpression.check(expression.callee) &&
!expression.callee.computed &&
n.Identifier.check(expression.callee.object) &&
expression.callee.object.name === "_" &&
n.Identifier.check(expression.callee.property) &&
["each", "forEach"].includes(expression.callee.property.name) &&
[2, 3].includes(expression.arguments.length) &&
checkExpression(expression.arguments[0]) &&
(n.FunctionExpression.check(expression.arguments[1]) ||
n.ArrowFunctionExpression.check(expression.arguments[1])) &&
[1, 2].includes(expression.arguments[1].params.length) &&
n.Identifier.check(expression.arguments[1].params[0]) &&
((valueOnly = expression.arguments[1].params[1] === undefined) ||
n.Identifier.check(expression.arguments[1].params[1])) &&
(expression.arguments[2] === undefined ||
n.ThisExpression.check(expression.arguments[2]))
) {
const old = { inLoop, replaceReturn };
inLoop = false;
replaceReturn = true;
this.visit(
path
.get("expression")
.get("arguments")
.get(1)
.get("body")
);
inLoop = old.inLoop;
replaceReturn = old.replaceReturn;
const [right, { body, params }] = expression.arguments;
const loop = b.forOfStatement(
b.variableDeclaration("let", [
b.variableDeclarator(
valueOnly ? params[0] : b.arrayPattern([params[1], params[0]])
),
]),
valueOnly
? right
: b.callExpression(
b.memberExpression(right, b.identifier("entries")),
[]
),
checkStatement(body) ? body : b.expressionStatement(body)
);
loop.comments = comments;
path.replace(loop);
changed = true;
}
this.traverse(path);
},
visitForStatement: visitLoop("init", "test", "update"),
visitForInStatement: visitLoop("left", "right"),
visitForOfStatement: visitLoop("left", "right"),
visitFunction(path) {
this.visit(path.get("params"));
const old = { replaceReturn };
replaceReturn = false;
this.visit(path.get("body"));
replaceReturn = old.replaceReturn;
return false;
},
visitReturnStatement(path) {
if (replaceReturn) {
assert(!inLoop); // could use labeled continue if this ever fires
const { argument, comments } = path.node;
if (argument === null) {
const s = b.continueStatement();
s.comments = comments;
path.replace(s);
} else {
const s = b.expressionStatement(argument);
s.comments = comments;
path.replace(s, b.continueStatement());
}
return false;
}
this.traverse(path);
},
visitWhileStatement: visitLoop("test"),
});
if (changed) {
console.log("Writing", file);
fs.writeFileSync(file, recast.print(ast).code, { encoding: "utf8" });
}
}
Signed-off-by: Anders Kaseorg <anders@zulipchat.com>
2020-02-06 06:19:47 +01:00
|
|
|
}
|
2014-03-13 19:03:31 +01:00
|
|
|
}
|
|
|
|
|
2018-07-26 20:17:34 +02:00
|
|
|
function set_user_list_heights(res, usable_height, buddy_list_wrapper, group_pms) {
|
2014-03-13 19:03:31 +01:00
|
|
|
// Calculate these heights:
|
2018-07-26 20:17:34 +02:00
|
|
|
// res.buddy_list_wrapper_max_height
|
2014-03-13 19:03:31 +01:00
|
|
|
// res.group_pms_max_height
|
2019-11-02 00:06:25 +01:00
|
|
|
const blocks = [
|
2014-03-13 19:03:31 +01:00
|
|
|
{
|
2019-03-01 01:40:05 +01:00
|
|
|
real_height: ui.get_scroll_element(buddy_list_wrapper).prop('scrollHeight'),
|
2014-03-13 19:03:31 +01:00
|
|
|
},
|
|
|
|
{
|
2019-03-01 01:40:05 +01:00
|
|
|
real_height: ui.get_scroll_element(group_pms).prop('scrollHeight'),
|
2017-01-12 00:17:43 +01:00
|
|
|
},
|
2014-03-13 19:03:31 +01:00
|
|
|
];
|
|
|
|
|
|
|
|
size_blocks(blocks, usable_height);
|
|
|
|
|
2018-07-26 20:17:34 +02:00
|
|
|
res.buddy_list_wrapper_max_height = blocks[0].max_height;
|
2014-03-13 19:03:31 +01:00
|
|
|
res.group_pms_max_height = blocks[1].max_height;
|
|
|
|
}
|
|
|
|
|
|
|
|
function get_new_heights() {
|
2019-11-02 00:06:25 +01:00
|
|
|
const res = {};
|
|
|
|
const viewport_height = message_viewport.height();
|
|
|
|
const top_navbar_height = $("#top_navbar").safeOuterHeight(true);
|
|
|
|
const invite_user_link_height = $("#invite-user-link").safeOuterHeight(true) || 0;
|
2014-03-13 19:03:31 +01:00
|
|
|
|
|
|
|
res.bottom_whitespace_height = viewport_height * 0.4;
|
|
|
|
|
|
|
|
res.main_div_min_height = viewport_height - top_navbar_height;
|
|
|
|
|
2019-02-10 02:04:14 +01:00
|
|
|
res.stream_filters_max_height = viewport_height
|
|
|
|
- parseInt($("#left-sidebar").css("marginTop"), 10)
|
|
|
|
- parseInt($(".narrows_panel").css("marginTop"), 10)
|
|
|
|
- parseInt($(".narrows_panel").css("marginBottom"), 10)
|
2017-07-27 21:40:26 +02:00
|
|
|
- $("#global_filters").safeOuterHeight(true)
|
2019-02-07 20:22:32 +01:00
|
|
|
- $("#streams_header").safeOuterHeight(true);
|
2014-03-13 19:03:31 +01:00
|
|
|
|
|
|
|
// Don't let us crush the stream sidebar completely out of view
|
2017-01-09 11:38:38 +01:00
|
|
|
res.stream_filters_max_height = Math.max(80, res.stream_filters_max_height);
|
2014-03-13 19:03:31 +01:00
|
|
|
|
|
|
|
// RIGHT SIDEBAR
|
2019-11-02 00:06:25 +01:00
|
|
|
const buddy_list_wrapper = $('#buddy_list_wrapper').expectOne();
|
|
|
|
const group_pms = $('#group-pms').expectOne();
|
2014-03-13 19:03:31 +01:00
|
|
|
|
2020-05-27 19:47:10 +02:00
|
|
|
// Calculate our top offset, which should typically be 50px,
|
|
|
|
// even though we sometimes split that as 40px of margin
|
|
|
|
// and 10px of padding, and other times its just 50px of
|
|
|
|
// margin. (See the commit message for this comment for
|
|
|
|
// more history).
|
|
|
|
|
|
|
|
const top_offset = $('#right-sidebar').position().top * -1;
|
|
|
|
|
|
|
|
if (top_offset !== 0 && top_offset !== 50) {
|
|
|
|
// If somebody changes the CSS for the right-sidebar without
|
|
|
|
// re-testing this code, it might introduce subtle bugs. I
|
|
|
|
// am only making it a warning, since I think we have some
|
|
|
|
// legacy media rules for really old screens that might trigger
|
|
|
|
// this.
|
|
|
|
blueslip.warn('Possibly unexpected `top` for #right-sidebar is: ' + top_offset);
|
|
|
|
}
|
|
|
|
|
2019-11-02 00:06:25 +01:00
|
|
|
const usable_height = viewport_height
|
2020-05-27 19:47:10 +02:00
|
|
|
- top_offset
|
2017-07-27 21:40:26 +02:00
|
|
|
- $("#userlist-header").safeOuterHeight(true)
|
2019-02-10 19:58:59 +01:00
|
|
|
- $("#user_search_section").safeOuterHeight(true)
|
2014-03-13 19:03:31 +01:00
|
|
|
- invite_user_link_height
|
2018-12-07 21:21:39 +01:00
|
|
|
- parseInt(group_pms.css("marginTop"), 10)
|
2014-03-13 19:03:31 +01:00
|
|
|
- parseInt(group_pms.css("marginBottom"), 10)
|
2018-05-08 00:04:58 +02:00
|
|
|
- $("#group-pm-header").safeOuterHeight(true)
|
2019-02-10 20:07:51 +01:00
|
|
|
- $("#sidebar-keyboard-shortcuts").safeOuterHeight(true);
|
2014-03-13 19:03:31 +01:00
|
|
|
|
|
|
|
// set these
|
2018-07-26 20:17:34 +02:00
|
|
|
// res.buddy_list_wrapper_max_height
|
2014-03-13 19:03:31 +01:00
|
|
|
// res.group_pms_max_height
|
|
|
|
set_user_list_heights(
|
|
|
|
res,
|
|
|
|
usable_height,
|
2018-07-26 20:17:34 +02:00
|
|
|
buddy_list_wrapper,
|
2014-03-13 19:03:31 +01:00
|
|
|
group_pms
|
|
|
|
);
|
|
|
|
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
|
|
|
function left_userlist_get_new_heights() {
|
|
|
|
|
2019-11-02 00:06:25 +01:00
|
|
|
const res = {};
|
|
|
|
const viewport_height = message_viewport.height();
|
|
|
|
const viewport_width = message_viewport.width();
|
2019-02-11 16:26:14 +01:00
|
|
|
res.viewport_height = viewport_height;
|
|
|
|
res.viewport_width = viewport_width;
|
|
|
|
|
|
|
|
// main div
|
2019-11-02 00:06:25 +01:00
|
|
|
const top_navbar_height = $(".header").safeOuterHeight(true);
|
2019-02-11 16:26:14 +01:00
|
|
|
res.bottom_whitespace_height = viewport_height * 0.4;
|
|
|
|
res.main_div_min_height = viewport_height - top_navbar_height;
|
|
|
|
|
2014-03-13 19:03:31 +01:00
|
|
|
|
2019-02-11 16:26:14 +01:00
|
|
|
// left sidebar
|
2019-11-02 00:06:25 +01:00
|
|
|
const stream_filters = $('#stream_filters').expectOne();
|
|
|
|
const buddy_list_wrapper = $('#buddy_list_wrapper').expectOne();
|
2014-03-13 19:03:31 +01:00
|
|
|
|
2019-11-02 00:06:25 +01:00
|
|
|
const stream_filters_real_height = stream_filters.prop("scrollHeight");
|
|
|
|
const user_list_real_height = ui.get_scroll_element(buddy_list_wrapper).prop("scrollHeight");
|
2014-03-13 19:03:31 +01:00
|
|
|
|
2019-02-10 02:04:14 +01:00
|
|
|
res.total_leftlist_height = viewport_height
|
2018-12-07 21:21:39 +01:00
|
|
|
- parseInt($("#left-sidebar").css("marginTop"), 10)
|
2019-02-10 02:04:14 +01:00
|
|
|
- parseInt($(".narrows_panel").css("marginTop"), 10)
|
|
|
|
- parseInt($(".narrows_panel").css("marginBottom"), 10)
|
2017-07-27 21:40:26 +02:00
|
|
|
- $("#global_filters").safeOuterHeight(true)
|
|
|
|
- $("#streams_header").safeOuterHeight(true)
|
|
|
|
- $("#userlist-header").safeOuterHeight(true)
|
2019-02-10 19:58:59 +01:00
|
|
|
- $("#user_search_section").safeOuterHeight(true)
|
2020-05-27 18:05:29 +02:00
|
|
|
- parseInt(stream_filters.css("marginBottom"), 10);
|
2014-03-13 19:03:31 +01:00
|
|
|
|
2019-11-02 00:06:25 +01:00
|
|
|
const blocks = [
|
2014-03-13 19:03:31 +01:00
|
|
|
{
|
2017-01-12 00:17:43 +01:00
|
|
|
real_height: stream_filters_real_height,
|
2014-03-13 19:03:31 +01:00
|
|
|
},
|
|
|
|
{
|
2017-01-12 00:17:43 +01:00
|
|
|
real_height: user_list_real_height,
|
2014-03-13 19:03:31 +01:00
|
|
|
},
|
|
|
|
];
|
|
|
|
|
|
|
|
size_blocks(blocks, res.total_leftlist_height);
|
|
|
|
|
|
|
|
res.stream_filters_max_height = blocks[0].max_height;
|
2018-07-26 20:17:34 +02:00
|
|
|
res.buddy_list_wrapper_max_height = blocks[1].max_height;
|
css: Remove Group PMs from **left** sidebar.
First, we are not removing Group PMs from the
right sidebar, where most people see it.
There is a setting called:
[ ] User list in left sidebar in narrow windows
There are probably very few people that turn that on,
and even when they do, the setting only takes effect
when your window is less than a certain width.
This feature bitrots very quickly, because very few
core maintainers use it.
It's already kind of broken. It gets very crowded,
and we get CSS bugs when we move the right sidebar
into the left sidebar. (We can fix those bugs, but
they crop up unexpectedly due to the nature of CSS.)
We historically tried to maintain a ratio between
stream list, single-user buddy list, and group-user
buddy list, but the group-user buddy list gets
particularly crowded out, and it's basically useless
now.
We want to revisit the entire feature eventually, but
this commit at least gives the normal buddy list some
breathing room.
Also, if you need to see the info in the group PM
list, you can basically expand "Private Messages" to
see your recent group PM conversations. And if you
want to see who's actually online, that info is
already implicit from the normal buddy list.
2019-02-10 02:39:12 +01:00
|
|
|
res.group_pms_max_height = 0;
|
2014-03-13 19:03:31 +01:00
|
|
|
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
2017-04-22 22:34:18 +02:00
|
|
|
exports.watch_manual_resize = function (element) {
|
2017-04-26 04:30:35 +02:00
|
|
|
return (function on_box_resize(cb) {
|
2019-11-02 00:06:25 +01:00
|
|
|
const box = document.querySelector(element);
|
2017-05-11 18:28:33 +02:00
|
|
|
|
|
|
|
if (!box) {
|
|
|
|
blueslip.error('Bad selector in watch_manual_resize: ' + element);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2019-11-02 00:06:25 +01:00
|
|
|
const meta = {
|
2017-05-11 18:28:33 +02:00
|
|
|
box: box,
|
2017-04-22 22:34:18 +02:00
|
|
|
height: null,
|
|
|
|
mousedown: false,
|
|
|
|
};
|
|
|
|
|
2019-11-02 00:06:25 +01:00
|
|
|
const box_handler = function () {
|
2017-04-22 22:34:18 +02:00
|
|
|
meta.mousedown = true;
|
|
|
|
meta.height = meta.box.clientHeight;
|
2017-04-26 04:30:35 +02:00
|
|
|
};
|
|
|
|
meta.box.addEventListener("mousedown", box_handler);
|
2017-04-22 22:34:18 +02:00
|
|
|
|
|
|
|
// If the user resizes the textarea manually, we use the
|
|
|
|
// callback to stop autosize from adjusting the height.
|
2019-11-02 00:06:25 +01:00
|
|
|
const body_handler = function () {
|
2017-04-22 22:34:18 +02:00
|
|
|
if (meta.mousedown === true) {
|
|
|
|
meta.mousedown = false;
|
|
|
|
if (meta.height !== meta.box.clientHeight) {
|
|
|
|
meta.height = meta.box.clientHeight;
|
|
|
|
cb.call(meta.box, meta.height);
|
|
|
|
}
|
|
|
|
}
|
2017-04-26 04:30:35 +02:00
|
|
|
};
|
|
|
|
document.body.addEventListener("mouseup", body_handler);
|
|
|
|
|
|
|
|
return [box_handler, body_handler];
|
2017-04-22 22:34:18 +02:00
|
|
|
}(function (height) {
|
|
|
|
// This callback disables autosize on the textarea. It
|
|
|
|
// will be re-enabled when this component is next opened.
|
2019-07-16 20:19:11 +02:00
|
|
|
autosize.destroy($(element))
|
2017-04-22 22:34:18 +02:00
|
|
|
.height(height + "px");
|
|
|
|
}));
|
|
|
|
};
|
|
|
|
|
2014-03-13 19:03:31 +01:00
|
|
|
exports.resize_bottom_whitespace = function (h) {
|
2020-05-27 21:08:13 +02:00
|
|
|
$("#bottom_whitespace").height(h.bottom_whitespace_height);
|
2014-03-13 19:03:31 +01:00
|
|
|
};
|
|
|
|
|
2015-11-25 18:41:32 +01:00
|
|
|
exports.resize_stream_filters_container = function (h) {
|
|
|
|
h = narrow_window ? left_userlist_get_new_heights() : get_new_heights();
|
|
|
|
exports.resize_bottom_whitespace(h);
|
|
|
|
$("#stream-filters-container").css('max-height', h.stream_filters_max_height);
|
|
|
|
};
|
|
|
|
|
2020-05-27 21:37:01 +02:00
|
|
|
exports.resize_sidebars = function () {
|
2019-11-02 00:06:25 +01:00
|
|
|
let sidebar;
|
2014-03-13 19:03:31 +01:00
|
|
|
|
2015-08-20 23:59:44 +02:00
|
|
|
if (page_params.left_side_userlist) {
|
2019-11-02 00:06:25 +01:00
|
|
|
const css_narrow_mode = message_viewport.is_narrow();
|
2014-03-13 19:03:31 +01:00
|
|
|
|
|
|
|
$("#top_navbar").removeClass("rightside-userlist");
|
|
|
|
|
2019-11-02 00:06:25 +01:00
|
|
|
const right_items = $('.right-sidebar-items').expectOne();
|
2019-02-10 20:36:36 +01:00
|
|
|
|
2014-03-13 19:03:31 +01:00
|
|
|
if (css_narrow_mode && !narrow_window) {
|
|
|
|
// move stuff to the left sidebar (skinny mode)
|
|
|
|
narrow_window = true;
|
|
|
|
popovers.set_userlist_placement("left");
|
2019-02-10 20:36:36 +01:00
|
|
|
sidebar = $("#left-sidebar").expectOne();
|
|
|
|
sidebar.append(right_items);
|
2018-07-26 20:17:34 +02:00
|
|
|
$("#buddy_list_wrapper").css("margin", "0px");
|
2014-03-13 19:03:31 +01:00
|
|
|
$("#userlist-toggle").css("display", "none");
|
|
|
|
$("#invite-user-link").hide();
|
2016-06-09 23:05:34 +02:00
|
|
|
} else if (!css_narrow_mode && narrow_window) {
|
2014-03-13 19:03:31 +01:00
|
|
|
// move stuff to the right sidebar (wide mode)
|
|
|
|
narrow_window = false;
|
|
|
|
popovers.set_userlist_placement("right");
|
|
|
|
sidebar = $("#right-sidebar").expectOne();
|
2019-02-10 20:36:36 +01:00
|
|
|
sidebar.append(right_items);
|
2018-07-26 20:17:34 +02:00
|
|
|
$("#buddy_list_wrapper").css("margin", '');
|
2014-03-13 19:03:31 +01:00
|
|
|
$("#userlist-toggle").css("display", '');
|
|
|
|
$("#invite-user-link").show();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-10-26 00:11:05 +02:00
|
|
|
const h = narrow_window ? left_userlist_get_new_heights() : get_new_heights();
|
2014-03-13 19:03:31 +01:00
|
|
|
|
2018-07-26 20:17:34 +02:00
|
|
|
$("#buddy_list_wrapper").css('max-height', h.buddy_list_wrapper_max_height);
|
2014-03-13 19:03:31 +01:00
|
|
|
$("#group-pms").css('max-height', h.group_pms_max_height);
|
|
|
|
|
2018-03-12 03:40:56 +01:00
|
|
|
$("#stream-filters-container").css('max-height', h.stream_filters_max_height);
|
2017-10-13 00:13:51 +02:00
|
|
|
|
2020-05-27 21:37:01 +02:00
|
|
|
return h;
|
|
|
|
};
|
|
|
|
|
|
|
|
exports.resize_page_components = function () {
|
|
|
|
const h = exports.resize_sidebars();
|
|
|
|
exports.resize_bottom_whitespace(h);
|
2018-01-31 01:11:21 +01:00
|
|
|
panels.resize_app();
|
2014-03-13 19:03:31 +01:00
|
|
|
};
|
|
|
|
|
2019-11-02 00:06:25 +01:00
|
|
|
let _old_width = $(window).width();
|
2014-03-13 19:03:31 +01:00
|
|
|
|
2016-12-02 14:06:06 +01:00
|
|
|
exports.handler = function () {
|
2019-11-02 00:06:25 +01:00
|
|
|
const new_width = $(window).width();
|
2014-03-13 19:03:31 +01:00
|
|
|
|
|
|
|
if (new_width !== _old_width) {
|
|
|
|
_old_width = new_width;
|
2014-03-13 20:22:09 +01:00
|
|
|
condense.clear_message_content_height_cache();
|
2014-03-13 19:03:31 +01:00
|
|
|
}
|
|
|
|
|
2019-03-15 04:02:27 +01:00
|
|
|
// On mobile web, we want to avoid hiding a popover here,
|
|
|
|
// especially if this resize was triggered by a virtual keyboard
|
|
|
|
// popping up when the user opened that very popover.
|
2019-11-02 00:06:25 +01:00
|
|
|
const mobile = util.is_mobile();
|
2019-03-15 04:02:27 +01:00
|
|
|
if (!mobile) {
|
|
|
|
popovers.hide_all();
|
|
|
|
}
|
2014-03-13 19:03:31 +01:00
|
|
|
exports.resize_page_components();
|
|
|
|
|
2018-03-26 19:26:24 +02:00
|
|
|
// Re-compute and display/remove [More] links to messages
|
2020-04-02 15:20:24 +02:00
|
|
|
condense.condense_and_collapse($(".message_table .message_row"));
|
2018-03-26 19:26:24 +02:00
|
|
|
|
2014-03-13 19:03:31 +01:00
|
|
|
// This function might run onReady (if we're in a narrow window),
|
|
|
|
// but before we've loaded in the messages; in that case, don't
|
|
|
|
// try to scroll to one.
|
|
|
|
if (current_msg_list.selected_id() !== -1) {
|
2019-03-15 04:02:27 +01:00
|
|
|
if (mobile) {
|
|
|
|
popovers.set_suppress_scroll_hide();
|
|
|
|
}
|
|
|
|
|
2016-05-25 13:26:57 +02:00
|
|
|
navigate.scroll_to_selected();
|
2014-03-13 19:03:31 +01:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2019-10-25 09:45:13 +02:00
|
|
|
window.resize = exports;
|