Commit Graph

56 Commits

Author SHA1 Message Date
Anders Kaseorg f47090136d js: Convert static/js/stream_muting.js to ES6 module.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2021-02-28 14:23:00 -08:00
Anders Kaseorg 245d6c3a3e js: Convert static/js/stream_data.js to ES6 module.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2021-02-28 14:23:00 -08:00
Anders Kaseorg d81ba3698f js: Convert static/js/stream_color.js to ES6 module.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2021-02-28 14:23:00 -08:00
Anders Kaseorg 374dfc2fda js: Convert static/js/color_data.js to ES6 module.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2021-02-28 14:23:00 -08:00
Anders Kaseorg b830f53eb5 js: Convert static/js/narrow_state.js to ES6 module.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2021-02-28 14:23:00 -08:00
Aman Agrawal e887428dec stream_events: Re-render RT after a stream is (un)muted.
We manually trigger a re-render of RT after a stream is muted
to update the list of topic in RT for the active filter.

This fixes the bug that RT doesn't update correctly
after a stream is muted.
2021-02-25 17:31:33 -08:00
Anders Kaseorg aa650a4c88 js: Escape strings interpolated into CSS selectors with CSS.escape.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2021-02-04 11:00:06 -08:00
Steve Howell 355f44ef13 refactor: Only pass stream_id for set_subscribers.
The goal here is to make all our peer_data functions
basically work in id space.  Passing a full `sub`
to these functions is a legacy of when subscriber
info was attached to a full stream "sub" object,
but we don't care about anything sub-related
(color, description, name, etc.) when we are
dealing with subscriptions.

When callers pass in stream_id, you can be more
confident in a quick skim of the code that we're
not mutating anything in the "sub".
2021-01-17 10:40:17 -08:00
Steve Howell 6cc880c858 refactor: Extract peer_data.js.
This de-clutters stream_data a bit.  Since our
peer data is our biggest performance concern,
I want to contain any optimizations to a fairly
well-focused module.

The name `peer_data` is a bit of a compromise,
since we already have `subs.js` and we use
`sub` as a variable name for stream records
throughout our code, but it's consistent with
our event nomenclature (peer/add, peer/remove)
and it's short while still being fairly easy
to find with grep.
2021-01-17 10:40:17 -08: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
YashRE42 b4891a5841 navbar: Rename tab_bar to message_view_header.
Prior to commit eb4a2b9d4e the center
area of the navbar was based on a structure that appended crumbs or
"tabs" as <li>s, forming a tab_bar and a tab_list.

However, in eb4a2b9d4e we apply a new
style and structure to the navbar which lets go of the convention of
tabs. Hence, we'd like to purge the tab_bar and tab_list labels from
our code base.

We purged tab_list in 1267caf5009118875f47fdafe312880af08024e1.

This commit purges tab_bar, it includes:
- A blanket search and replace of tab_bar with message_view_header.
- Splitting a single line comment in
  tab_bar.js / message_view_header.js.
- The renaming of tab_bar.js to message_view_header.js.
- The renaming of tab_bar.hbs to message_view_header.hbs.
- A blanket search and replace of tab_data with
  message_view_header_data.
- Replacing the single occurrence of tabbar with message_view_header
  (it was within a comment.)
2020-07-30 16:23:13 -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 b65d2e063d js: Reformat with Prettier.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2020-07-17 14:31:25 -07:00
Anders Kaseorg 6924d501bc js: Indent case clauses in switch statements.
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: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
YashRE42 25765faf58 navbar: Live update sub_count.
Previously, the navbar sub count would not live update as users
subscribed or unsubscribed, this commit adds the relevant calls in
stream events.

It would have been better to just have a single call within
server_events_dispatch but it seems difficult due to the way of
mark_subscribed and mark_unsubscribed are structured.

stream_events.mark_unsubscribed conditionally calls
subs.update_settings_for_unsubscribed which calls
subs.rerender_subscriptions_settings and as such handles the update
for the subscriptions modal on its own. Hence, we simply rely on the
stream_data.update_calculated_fields to ensure the subscriber counts
are updated and make a call to
tab_bar.maybe_rerender_title_area_for_stream(sub).

stream_events.mark_subscribed is similar.
2020-07-13 15:38:15 -07:00
sahil839 a0d2c7db16 stream_data: Modify is_user_subscribed to use stream id.
This commit changes stream_data.is_user_subscribed to use stream id
instead of stream name.
We are using stream ids so that we can avoid bugs related to live
update after stream rename.
2020-07-13 13:09:17 -07:00
sahil839 235601d3b6 stream_data: Modify remove_subscriber to use stream id.
This commit changes stream_data.remove_subscriber to use stream id
instead of stream name. We are using stream ids so that we can
avoid bugs related to live update after stream rename.
2020-06-22 13:39:47 -07:00
sahil839 821e25ffb0 streams: Show message retention policy details in subscription_type text.
This commit adds message retention policy details in the subscription_type
text below the stream description.

We do not show any text when realm-level settings is set to forever and
stream-level is set to either forever or realm_default.
2020-06-18 17:13:04 -07:00
sahil839 d9b7228444 streams: Add frontend to set/update message_retention_days of a stream.
This commit adds frontend support for setting and updating message
retention days of a stream from stream settings.

Message retention days can be changed from stream privacy modal of the
stream and can be set from stream_creation_form while creating streams.

Only admins can create streams with message_retention_days value other
than realm_default.

This commit also contains relevant changes to docs.
2020-06-18 17:00:34 -07:00
Steve Howell 9fdd98cf88 refactor: Clean up add/remove_sidebar_row.
The stream_events tests were kinda messy, but
I mostly just consolidated a few sections of
code so that we didn't have to keep
re-stubbing the same functions.

For the actual code, I extracted add_sidebar_row
and then removed the unnecessarily complicated
jQuery trigger mechanisms.
2020-06-18 09:08:46 -07:00
Ryan Rehman 5a5fc6caa1 stream edit: Fix real-time sync of stream notification setting.
The UI in the `#settings/notifications` page is updated similarly
to what is done in the `update_global_notifications` path present
in the `server_events_dispatch` file.
2020-04-01 14:40:41 -07:00
Ryan Rehman e845b2364f refactor: Remove redundant block in `stream_edit.stream_setting_clicked`.
Currently we are updating the checkbox UI as soon as the user clicks.
This block is removed to match with the pattern of rest of the
properties in the stream edit page where `stream_events.update_property`
is responsible for updating the UI after a successful server response.
2020-03-31 15:36:59 -07: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
Ryan Rehman 174b2abcfd settings: Migrate to stream_post_policy structure.
This commit includes a new `stream_post_policy` setting,
by replacing the `is_announcement_only` field from the Stream model,
which is done by mirroring the structure of the existing
`create_stream_policy`.

It includes the necessary schema and database migrations to migrate
the is_announcement_only boolean field to stream_post_policy,
a smallPositiveInteger field similar to many other settings.

This change is done to allow organization administrators to restrict
new members from creating and posting to a stream. However, this does
not affect admins who are new members.

With many tweaks by tabbott to documentation under /help, etc.

Fixes #13616.
2020-02-04 17:08:08 -08:00
Nat1405 d5f005fd61 wildcard_mentions_notify: Add per-stream override of global setting.
Adds required API and front-end changes to modify and read the
wildcard_mentions_notify field in the Subscription model.

It includes front-end code to add the setting to the user's "manage
streams" page. This setting will be greyed out when a stream is muted.
The PR also includes back-end code to add the setting the initial state of
a subscription.

New automated tests were added for the API, events system and front-end.
In manual testing, we checked that modifying the setting in the front end
persisted the change in the Subscription model. We noticed the notifications
were not behaving exactly as expected in manual testing; see
https://github.com/zulip/zulip/issues/13073#issuecomment-560263081 .

Tweaked by tabbott to fix real-time synchronization issues.

Fixes: #13429.
2019-12-09 16:09:38 -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
Yashashvi Dave 02e82ef10c static/js/stream_events: Deduplicate notification settings updates. 2019-06-24 14:46:45 -07:00
Yashashvi Dave 1f5720d1b8 stream settings: Add `name` attr to settings elements.
Add `name` attribute to stream settings `input` elements
and change `id` attribute corresponding to name.
`name` attribute stores value of settings name which is
stored in frontend data sets.
2019-06-24 14:46:45 -07:00
Yashashvi Dave 2a943d3b40 static/js/stream_muting: Rename `update_in_home_view` function. 2019-05-30 21:39:06 -07:00
Harshit Bansal b553507412 subscriptions: Migrate notification setting defaults model.
This commit migrates the Subscription's notification fields from a
BooleanField to a NullBooleanField where a value of None means to
inherit the value from user's profile.

Also includes a migrations to set the corresponding settings to None
if they match the user profile's values. This migration helps us in
getting rid of the weird "Apply to all" widget that we offered on
subscription settings page.

The mobile apps can't handle None appearing as the stream-level
notification settings, so for backwards-compatibility we arrange to
only send True/False to the mobile apps by applying those defaults
server-side.  We introduce a notification_settings_null value within a
client_capabilities structure that newer versions of the mobile apps
can use to request the new model.

This mobile compatibility code is pretty effectively tested by the
existing test_events tests for the subscriptions subsystem.
2019-05-08 17:45:10 -07:00
Yashashvi Dave 02a1b2e26b server events: Add realm-time-sync event to update stream privacy.
Add event to update stream settings whenever stream privacy is changed
accordingly.

Fixes #9470
2019-05-07 17:33:59 -07:00
Yashashvi Dave a68a06d94f static/js/stream_events: Modify function `update_property`.
This commits modifies function `update_property` to
update more one stream-sub-property in one event.
2019-05-07 17:33:59 -07:00
Hemanth V. Alluri 683ec852fd stream_data: Use stream rendered_description provided by the backend.
Use the results of commit #73d26c8 to remove the method
`render_stream_description` in static/js/stream_data.js and instead
use the rendered_description attribute now being sent by the backend.

This will be a valuable optimization and a step towards removing the
need for the marked.js markdown parser and speeding up the client end.
2019-02-11 12:24:27 -08:00
Steve Howell ba243416e3 stream_color: Make stream color assignment more efficient.
We now let color_data keep its own state for
unused_colors, so that we longer have to pass in
a large list of unused_colors every time we want
to assign a new stream color.

This mostly matters at startup, where we might
be cycling through 5000 streams.  We claim all
the unused colors up front.

Each operation now has an upper bound of expensiveness,
where the worst case scenario is basically popping
off the first element of a list of <= 24 colors.

The algorithm is now deterministic, too, to make
it easier to test.  It's unclear whether random color
assignment ever had much benefit, and it made unit
testing the algorithm difficult.  Now we have 100%
line coverage.

Fixes part of #10902.
2018-11-29 13:00:25 -08:00
Steve Howell 6035304619 Extract color_data.js.
This code is pretty distinct from all the color-picking UI,
and we want to get it to 100% coverage and optimize it
more.
2018-11-28 14:51:51 -08:00
Tim Abbott 2c06615909 streams: Fix stream color synchronization.
Previously, when a new stream was created on a client other than the
current one, the browser would first receive the "stream_created"
event, and make up a client-side display color at that time to use in
the "stream settings" view (it doesn't yet know the color that was
selected when the user was actually subscribed, because it doesn't
even know yet that the user is being subscribed to this stream), and
then moments after it'll receive a "susbcribe" event letting the
client know that the user is subscribed (and specifying the color to
use).

However, due to an argument not being passed through properly and a
missing rerender, we were not properly updating either the data
structures or doing a stream colors rerender in order to show the new
color.

This fixes the issue reported in
https://chat.zulip.org/#narrow/stream/48-mobile/subject/stream.20colors/near/660170
2018-11-09 17:04:47 -08:00
Steve Howell ecb3879d0c refactor: Break subs dependency in stream_data.
We move remove_deactivated_user_from_all_streams
into stream_events.js.  There were some minor changes
to rename variables and also to not rely on using
`stream_info`.
2018-08-04 14:06:19 -07:00
Sarah de2ec8a05c notification settings: Add UI for stream email notifications.
Previous commits have fully implemented the logic for stream email
notifications; this final commit adds support for configuring it to
the UI.

Fixes #6511.
2018-07-14 12:19:33 +05:30
Armaan Ahluwalia 6d255efe4c app: Prepare JS files for consumption by webpack.
This commit prepares the frontend code to be consumed by webpack.

It is a hack: In theory, modules should be declaring and importing the
modules they depend on and the globals they expose directly.

However, that requires significant per-module work, which we don't
really want to block moving our toolchain to webpack on.

So we expose the modules by setting window.varName = varName; as
needed in the js files.
2018-07-05 10:53:36 +02:00
Tim Abbott 7ab8a8e820 js: Fix a bunch of indentation issues found by eslint.
This is preparation for enabling an eslint indentation configuration.
90% of these changes are just fixes for indentation errors that have
snuck into the codebase over the years; the others are more
significant reformatting to make eslint happy (that are not otherwise
actually improvements).

The one area that we do not attempt to work on here is the
"switch/case" indentation.
2018-05-06 16:25:02 -07:00
Shubham Padia 23e82315b5 stream-settings: Remove redundant actually_filter_streams function call.
After adding a newly created stream to the top of the stream list,
call to actually_filter_streams in stream_events.mark_subscribed
rerendered the filter_table and the stream list was refreshed.  The
call to actually_filter streams was introduced to rerender the
subscriber list but stream_edit.rerender_subscribers_list takes care
of it already.

Fixes #9033.
2018-04-30 11:38:47 -07:00
Tim Abbott c5904499db stream_data: Move calls to update_calculated_fields to events layer.
This migrates what were effectively data update functions to be called
from the main stream_events handlers, instead of being called from the
view-update code in subs.js.
2018-03-09 18:00:31 -08:00
Tim Abbott 9d0e1a2e0c subs: Don't try to update stream settings UI when closed.
The recent fixes we made to make stream settings update properly when
doing live updates were great, but they would throw an exception if
the stream settings overlay wasn't open.  This fixes that by adding
the appropriate check.
2017-10-23 22:44:27 -07:00
Tim Abbott 773f8fcb05 stream_events: Fix exceptions when subscribed by another client.
We were getting several exceptions in mark_subscribed if the streams
overlay wasn't open, basically because we'd try to filter the
right-side stream list when it wasn't present in the DOM.
2017-10-17 23:42:29 -07:00
Brock Whittaker 20af49b2bb streams: Call `actually_filter_streams` on stream events update.
Previously it was called before the event was processed by the server
and the subscription was updated to have the user subscribed to a
stream, so there was a race condition that would make it iso that
sometimes the stream line would disappear on the next render pass due
to the event not having completed yet.

This makes it so that the re-render happens after the event is
processed in `stream_events.js`.

Fixes: #6797.
2017-10-11 12:44:10 -07:00
Steve Howell 3e6bfe1b23 Use user_ids, not emails, for bulk stream operations.
We now return user_ids for subscribers to streams in add-stream
events.  This allows us to eliminate the UserLite class for
both bulk adds and bulk removes.  It also simplifies some JS
code that already wanted to use user_ids, not emails.

Fixes #6898
2017-10-08 12:31:12 -07:00
Sarah c3a8138f74 user_settings: Add push notifications for all stream messages.
Add setting to enable push notifications for all stream messages.
2017-09-14 05:41:37 -07:00
Steve Howell 8eb86335b9 Extract narrow_state.js.
Despite the length of this commit, it is a very straightforward
moving of code from narrow.js -> narrow_state.js, and then
everything else is just s/narrow.foo()/narrow_state.foo()/
(with a few tiny cleanups to remove some code duplication
in certain callers).

The only new functions are simple setter/getters that
encapsulate the current_filter variable:

    narrow_state.reset_current_filter()
    narrow_state.set_current_filter()
    narrow_state.get_current_filter()

We removed narrow.predicate() as part of this, since it was dead
code.

Also, we removed the shim for narrow_state.set_compose_defaults(),
and since that was the last shim, we removed shim.js from the app.
2017-04-25 09:57:32 -07:00