Commit Graph

372 Commits

Author SHA1 Message Date
Ganesh Pawar e3a099d732 deprecated_feature_notice: Move code to a separate module. 2021-06-15 11:58:45 -07:00
Ganesh Pawar fe147757c9 refactor: Migrate Bootstrap modal calls to `overlay` calls.
In d0f8515b50, it was noticed that
Bootstrap's `hide` and `show` calls can cause race conditions.
So, migrate to our `overlay` calls to handle Bootstrap modals.
2021-06-10 12:16:23 -07:00
Tim Abbott 3edb9b8ed6 tooltips: Use TippyJS for all message_control_button tooltips.
The inconsistent style between these three buttons looked bad.

We have to take some care with the "Starred messages" and "Edit" ones,
to make sure they live-update properly.
2021-05-13 12:56:38 -07:00
Anders Kaseorg 41dd50948a js: Consistently use ES module from SimpleBar.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2021-04-24 13:08:52 -07:00
Anders Kaseorg 2004a85fb1 i18n: Automatically convert remaining JavaScript messages to FormatJS.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2021-04-13 17:41:10 -07:00
Anders Kaseorg 2293b01a75 i18n: Fix uses of i18n.t on computed strings.
We don’t extract either of these strings correctly at present, but I’m
about to replace the entire frontend extraction system.

Signed-off-by: Anders Kaseorg <anders@zulip.com>
2021-04-13 17:41:10 -07:00
Anders Kaseorg 6f764ce4b3 message_list: Downgrade message_list.all to MessageListData.
This data structure has never been one that we actually render into
the DOM; instead, its role is to support clicking into view that
contain muted streams and topics quickly.

This downgrade makes that situation much more explicit, and is also
useful refactoring to help simpify the upcoming changes in #16746.

Signed-off-by: Anders Kaseorg <anders@zulip.com>
2021-03-30 08:33:47 -07:00
Anders Kaseorg d43ac7357a js: Move current_msg_list, home_msg_list to ES6 module message_lists.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2021-03-29 18:23:47 -07:00
Anders Kaseorg bb1b2048bd js: Convert static/js/i18n.js to ES6 module.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2021-03-26 10:17:56 -07:00
Anders Kaseorg 3ef6f6e2e2 js: Convert static/js/blueslip.js to ES6 module.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2021-03-17 08:47:15 -04:00
Anders Kaseorg ea9ca6b7d0 js: Use jQuery as a module.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2021-03-12 10:08:25 -08:00
Anders Kaseorg 5cc1f8d289 js: Convert static/js/ui.js to ES6 module.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2021-03-02 17:06:35 -08:00
Anders Kaseorg 7a67c06581 js: Convert static/js/message_list.js to ES6 module.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2021-03-02 17:06:35 -08:00
Anders Kaseorg a3e6ebb04c js: Convert static/js/common.js to ES6 module.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2021-02-28 14:23:00 -08:00
Anders Kaseorg f9c4b5438e js: Convert static/js/localstorage.js to ES6 module.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2021-02-23 20:36:01 -08:00
Anders Kaseorg 5a22e73cc6 ui: Remove warning for unsupported old Zulip desktop app.
This warning was added in #6551.  It’s not for any version of the
current Electron app, which we warn about on the server side with
DESKTOP_WARNING_VERSION, but rather some pre-Electron app so ancient I
don’t even know what it is.  Apparently it communicated using the
window.bridge global, so eradicate that too.

Signed-off-by: Anders Kaseorg <anders@zulip.com>
2021-02-23 18:14:12 -08:00
Chris Taylor e341a81987 Tooltip: edited tooltip string to add consistency in static/js/ui.js. 2021-02-09 10:44:21 -05:00
ryanreh99 e5779c1ca0 message events: Refactor `reify_message_id` codepath.
The changes made in this commit are as follows:

* The `remove_messages` is moved to the `message_events.js`
  file from `ui.js`.

* We refactor `MessageListData.change_message_id` to no
  longer require an `opts` parameter as this function
  just returns whether we need to rerender or not.

  The blueslip error block can be removed since we made
  the change to no long defer the data updates in
  commit 3b5ba6b2c1,
  this case can no longer occur.
2020-11-16 17:23:15 -08:00
ryanreh99 59e5f2d8fc message events: Refactor `remove_and_rerender` codepath.
The changes made in this commit are as follows:

* We remove the now unused `ui.find_message` which was added
  in commit 1666403850.

* We change the function paramter to now accept message ids
  instead of messages to eliminate redundant message ids to
  message convertion as only the id is required.

* The remove method in MessageListData did not remove the
  messages from the hash, it removed only from the items,
  this fixes it.

* This commit also fixes a bug where messages are not added
  to the current message list if an event is recieved where
  messages are moved to this current narrow.
  Only the message removal logic was present, which has been
  refactored in this commit.
2020-11-16 17:23:15 -08:00
Anders Kaseorg 3a39c6f67f dependencies: Downgrade simplebar to 5.2.1.
SimpleBar 6.0.0-beta.2 through -beta.6 are built with ES6 syntax (I
assume inadvertently: https://github.com/Grsmto/simplebar/issues/523),
and its latest tag has moved back to 5.2.1 anyway.

Signed-off-by: Anders Kaseorg <anders@zulip.com>
2020-09-24 16:13:47 -07:00
Anders Kaseorg 9238813135 js: Use destructuring for require statements.
This allows import/order to auto-fix blocks including these
statements.

Signed-off-by: Anders Kaseorg <anders@zulip.com>
2020-09-23 09:06:07 -04:00
Anders Kaseorg b00a0bfe53 js: Use simplebar ES module.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2020-09-15 16:33:28 -07:00
Anders Kaseorg 279e4b819e js: Elide .js and .ts extensions from imports and requires.
This will be required for TypeScript.

Signed-off-by: Anders Kaseorg <anders@zulip.com>
2020-09-01 16:43:02 -07:00
Tim Abbott beae13b4d6 recent_topics: Renaming confusingly named deletion handlers.
This functions were oddly named in a way that didn't make clear their
role in handling deleted messages.
2020-08-06 12:00:30 -07:00
Anders Kaseorg 6ec808b8df js: Add "use strict" directive to CommonJS files.
ES and TypeScript modules are strict by default and don’t need this
directive.  ESLint will remind us to add it to new CommonJS files and
remove it from ES and TypeScript modules.

Signed-off-by: Anders Kaseorg <anders@zulip.com>
2020-07-31 22:09:46 -07:00
Anders Kaseorg 96dcc0ce6e js: Use ES6 object literal shorthand syntax.
Generated by ESLint.

Signed-off-by: Anders Kaseorg <anders@zulip.com>
2020-07-21 12:42:22 -07:00
Anders Kaseorg a9ca5f603b js: Replace deprecated jQuery event trigger shorthand.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2020-07-21 12:01:26 -07:00
Anders Kaseorg 4e42137bd9 js: Replace deprecated jQuery event handler shorthand.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2020-07-21 12:01:26 -07:00
Anders Kaseorg b65d2e063d js: Reformat with Prettier.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2020-07-17 14:31:25 -07:00
Anders Kaseorg 883e2fd325 js: Remove inner spacing from object literals.
We’re configuring Prettier with bracketSpacing: false.  Generated by
ESLint.

Signed-off-by: Anders Kaseorg <anders@zulip.com>
2020-07-17 14:31:25 -07:00
Anders Kaseorg f3726db89a js: Normalize strings to double quotes.
Prettier would do this anyway, but it’s separated out for a more
reviewable diff.  Generated by ESLint.

Signed-off-by: Anders Kaseorg <anders@zulip.com>
2020-07-17 14:31:24 -07:00
Aman Agrawal 5d5434ec2f recent_topics: Update topics post message deletion.
Delete stored topic data in `recent_senders` and `recent_topics`
about the message's topics and re-render them. The process is similar
to topic editing. See `recent_senders.process_topic_edit` for
logical details.
2020-07-15 12:35:24 -07:00
SiddharthVarshney d0fd0cae3f message-controls: Use <i> tag for starred message icon.
Throughout the codebase we use <i> tag for icons.
This commit will add <i> tag inside the starred message
div and fa classes are now used with this <i> tag.

The starred message div is now consistent with other
message_controls divs.

Tweaked by tabbott to use the name star_container for better
readability.
2020-07-13 15:59:12 -07:00
Anders Kaseorg e014ea966a eslint: Enable comma-dangle for functions.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2020-07-03 16:55:51 -07:00
Anders Kaseorg a79322bc94 eslint: Enable prefer-arrow-callback.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2020-07-03 16:55:50 -07:00
Aman Agrawal 0cffaa7b5d ui: Upgrade remove_message to allow removing messages in bulk.
We simply pass the visible message ids to remove_and_rerender
which supports bulk delete operation.

This helps us avoid deleting messages in a loop which freezes the
UI for the duration of the loop.
2020-06-15 10:41:12 -07:00
Tim Abbott 71078adc50 docs: Update URLs to use https://zulip.com.
We're migrating to using the cleaner zulip.com domain, which involves
changing all of our links from ReadTheDocs and other places to point
to the cleaner URL.
2020-06-08 18:10:45 -07:00
Anders Kaseorg 719546641f js: Convert a.indexOf(…) !== -1 to a.includes(…).
Babel polyfills this for us for Internet Explorer.

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 K from "ast-types/gen/kinds";
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);

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;

  recast.visit(ast, {
    visitBinaryExpression(path) {
      const { operator, left, right } = path.node;
      if (
        n.CallExpression.check(left) &&
        n.MemberExpression.check(left.callee) &&
        !left.callee.computed &&
        n.Identifier.check(left.callee.property) &&
        left.callee.property.name === "indexOf" &&
        left.arguments.length === 1 &&
        checkExpression(left.arguments[0]) &&
        ((["===", "!==", "==", "!=", ">", "<="].includes(operator) &&
          n.UnaryExpression.check(right) &&
          right.operator == "-" &&
          n.Literal.check(right.argument) &&
          right.argument.value === 1) ||
          ([">=", "<"].includes(operator) &&
            n.Literal.check(right) &&
            right.value === 0))
      ) {
        const test = b.callExpression(
          b.memberExpression(left.callee.object, b.identifier("includes")),
          [left.arguments[0]]
        );
        path.replace(
          ["!==", "!=", ">", ">="].includes(operator)
            ? test
            : b.unaryExpression("!", test)
        );
        changed = true;
      }
      this.traverse(path);
    },
  });

  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-10 14:08:12 -08:00
Anders Kaseorg 02511bff1c 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-07 14:09:47 -08:00
Anders Kaseorg 2c4101dbc5 dependencies: Upgrade simplebar from 4.2.3 to 5.0.7.
Signed-off-by: Anders Kaseorg <anders@zulipchat.com>
2019-11-13 12:46:29 -08:00
Anders Kaseorg 28f3dfa284 js: Automatically convert var to let and const in most files.
This commit was originally automatically generated using `tools/lint
--only=eslint --fix`.  It was then modified by tabbott to contain only
changes to a set of files that are unlikely to result in significant
merge conflicts with any open pull request, excluding about 20 files.
His plan is to merge the remaining changes with more precise care,
potentially involving merging parts of conflicting pull requests
before running the `eslint --fix` operation.

Signed-off-by: Anders Kaseorg <anders@zulipchat.com>
2019-11-03 12:42:39 -08:00
Anders Kaseorg d17b577d0c js: Purge useless IIFEs.
With webpack, variables declared in each file are already file-local
(Global variables need to be explicitly exported), so these IIFEs are
no longer needed.

Signed-off-by: Anders Kaseorg <andersk@mit.edu>
2019-10-25 13:51:21 -07:00
Anders Kaseorg f0e0fe1c15 ui.get_scroll_element: Set up SimpleBar if it’s expected but missing.
Although SimpleBar automatically sets itself up on elements with a
`data-simplebar` attribute, sometimes we try to set event listeners
before that happens.  Create the SimpleBar early in that case.

Signed-off-by: Anders Kaseorg <anders@zulipchat.com>
2019-07-25 16:18:54 -07:00
Yashashvi Dave 371343709b static/js/common: Extract function `has_mac_keyboard`. 2019-06-24 14:04:42 -07:00
Anders Kaseorg 01613e71fb ui: Replace set_up_scrollbar with data-simplebar attribute.
With perfectScrollbar, we needed to call a function from JavaScript to
enable a scrollbar on a new element, but simplebar has a much simpler
default API one can do by using data-simplebar attributes in the HTML.

So we can delete all the scrollbar creation/deletion code.

Signed-off-by: Anders Kaseorg <anders@zulipchat.com>
2019-05-19 18:06:38 -07:00
Anders Kaseorg 141088586b Completely replace perfect-scrollbar with SimpleBar.
perfect-scrollbar replaces both the appearance and the behavior of the
scrollbar, and its emulated behavior will never feel native on most
platforms.  SimpleBar customizes the appearance while preserving the
native behavior.

Signed-off-by: Anders Kaseorg <andersk@mit.edu>
2019-05-17 12:06:51 -07:00
Steve Howell 82e453d9fe ui: Fix scrollbar regressions.
In between releases, the following commit introduced
a bug where we agressively scroll to the top every
place we call `ui.update_scrollbar`:

    092b73d0b7

The main symptoms were that the left and right sidebars
would go to the top for things like selecting a topic,
getting activity updates from the server, and resizing
the window.  It was very jarring.

The recent commit looked innocuous--the root of the problem
was the original API expressed an intent to scroll to the
top, but didn't actually do it, so it was a bug in hiding.

There are **some** occasions where it's actually appropriate
to scroll to the top, mostly around search filtering, and
in those places we now call the new `ui.reset_scrollbar`
function.

This is a bit of an emergency fix, so particularly with
the settings stuff, we may get more reports of glitches here.

The important thing here is that you almost never want to
reset the scrollTop for sidebars.
2019-01-09 09:15:45 -08:00
Steve Howell 995a26f4e5 ui: Explicity initialize night mode. 2019-01-04 10:54:10 -08:00
Shubham Dhama 092b73d0b7 ui: Fix wrong usage of scrolling to top in ui.updateScrollbar.
This was a bug introduced in 2363c9955a.

Fixes: #11141.
2019-01-02 11:00:01 -08:00
Akash Nimare dbb2d28ad6 hotkey: Update deprecation notice for '*' hotkey.
This PR updates the shortcut of the deprecation notice
for '*' hotkey. On macOS, it should be 'Cmd + s' instead
of 'Ctrl'.
2018-09-21 10:59:55 -07:00