This fixes an annoying bug where clicking to subscribe to a stream
would change the color shown in the "manage streams" UI immediately
after you click.
Fixes#11072.
This commit takes away the ability for non-admin members to create
streams where only admins can post messages by hiding the option from
them.
Fixes#11290.
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.
Guest users can not add subscribers to subscribed or unsubscribed
streams. Therefore hide add-subs html element if current user
is guest user.
Tweaked by tabbott to use the early-return pattern.
Add explanation in popover on disabled add-subscriptions input elements,
admin can't add subscribers to non subscribed private streams, only
subscribed users can.
Fixes#10593
This function used to be called initialize_from_page_params(),
and we called it indirectly through `subs.js`.
Now we call it directly from `ui_init.js`, which gives us a
bit more control over how things are initialized. In fact,
this sets us up for the next commit, where I fix a recent
regression I introduced.
Before this commit, we would sometimes have
the toggler handle clicking or arrowing to
the All tab, but then also rewrite the hash
which caused us to re-process the event.
Now we only call update_browser_history()
in the callback handler from the toggle widget.
There's a bit of refactoring to make this happen,
but the call stacks end up being this:
call toggler.goto(...)
# callback is dispatched
call subs.switch_stream_tab
actually_filter_streams
update_browser_history
While they can share some code, opening the edit panel
for a stream and clearing the panel are pretty different
actions, so we simplify the API for each thing.
You no longer have to pass in booleans, and for the clear
case, you don't have to pass in a bogus node that just
gets ignored.
This fixes a bug where hitting the "n" hotkey was
causing double work related to the hashchange system.
The code is now organized like this:
do_open_create_stream() does the GUI piece
We call the above directly for hash changes.
For in-app actions, whether clicks or hotkeys,
we call open_create_stream(), which delegates
most of the work to do_open_create_stream() but
also updates the hash.
When you unsubscribe a stream by clicking on the
checkmark, we don't want it to disappear right
away, but we also don't need it to stay around
once you start searching for new streams.
Note from Tim: This commit removes some complex code that was just a
workaround for the fact that this widget used to automatically
re-filter immediately after clicking to unsubscribe a user.
Since we've since fixed that original issue, we don't need this.
Earlier, on opening the subs modal, the "Subscribed" tab would be selected
by default when the components.toggle was created for tab switching.
This would change the hash to `#streams/subscribed`, and then extra work had
to be done to change it back to `#streams/all` leading to a longer open times.
With this change, `#streams` and `#streams/subscribed` both take you to
the "Subscribed Tab", and `#streams/all` takes you directly to
the "All Streams" tab.
This pulls the essential bucketing/sorting logic out
of filter_table().
The diff isn't quite as clean as I'd like, but some
of the code that got added back to filter_table() can be
eliminated in the future. Basically, all the stuff
related to hidden ids can just be zapped if we go
to an approach of just re-building the DOM cleanly
whenever our filters change.
We replace two calls to stream_matches_query() with
a single call to triage_stream(), which prevents us
from doing the same is-subscribed checks twice.
We probably should have done this a while ago, even
though these functions are pretty tiny. The goal here
is to make it easier to have more consistent search
semantics.
Our first use case is subs.js. In this case we
are able to decouple a bit of generic string
matching from the subs-specific code.
We move some data code from subs.js to stream_data.js.
It's not clear we have been using the optimal sort for
dealing with locales, but this change preserves the
current behavior. The only subtle change here is that
we look up subs using a Dict now instead of a plain
JS object.
We now render the "skin" part of "Stream Settings" before
adding in the actual streams. The new function
populate_stream_settings_left_panel() takes care of adding
the streams. It uses a new template called
`subscriptions.handlebars`.
Splitting out this function will give us more flexibility
for various improvements.
First, we can decide to render the list after we open the
overlay, just to avoid the problem that users don't know why
the modal's opening. (And we could add a loader spinner as
needed.)
Second, we can improve our filter features so that we do
filtering in the data instead of moving DOM rows around,
which is expensive.
Third, we can eventually introduce progressive rendering.
Finally, having the function broken out will make profiling
more precise about where bottlenecks exist.
This behavior was originally implemented in commit 6993f89, but due to not
specifying a toggle option, the Subscribed/All streams switcher tab was
focused after the input was focused, leading to the input's loss of focus.
Fixes#9981.
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.
This cleans up some leftover js and css from the effort of
redesign the rows of the #subscriptions table. Redesign happened
in commit 368b5859 and but we forgot to clean up these js and css
pieces.
squash to subs.js.
When admin user create new private stream, widget for changing privacy
of stream doesn't render. Because we render subscription-settings
template partially on subscription-add event, so this case wasn't
handled.
Fixes#9469
We now initialize most modules in ui_init.js, which
isn't the perfect place to do it, but at least now
we have a mostly consolidated entry point.
All the new foo.initialize() methods introduced in
this module run the same order relative to each
other as before this commit. (I did some console
logging with a hacked version of the program to
get the order right.) They happen a bit later than
before, though.
A couple modules still have the `$(function() {`
idiom for miscellaneous reasons:
archive - is a different bundle
common - used elsewhere
list_render - non-standard code style
scroll_bar - no exports
setup - probably special?
socket - $(function () is nested!
transmit - coupled to socket
translations - i18n is a bigger problem
ui_init - this bootstraps everything
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.
We now have components.toggle simply return an object, without
putting the object into a lookup table. The consumers of the
objects have all been changed to just store the object in their
own module scope.
The diff is a bit hard to read here, but it's mostly de-denting
code and removing these things:
- we don't have opts.name
- we don't have __toggle.lookup
- we don't have keys
- we don't create a sibling object to the prototype object
This commit introduces a helper function called
maybe_select_tab() that goes to the correct tab in the
toggler widget.
It avoids the "lookup" mechanism, which I am hoping to
deprecate, and it handles hypothetical startup issues
by warning instead of crashing.
Before this commit, this sequence would lead to errors:
* Open streams page via the gear menu.
* Go to "All" tab.
* Leave streams settings.
* Re-open stream settings via the gear menu.
After doing this, the tab would show "Subscribed" but the list
would be of all messages.
Now we explicitly goto the first tab.
I added a long comment explaining how subs.js contributed
to this bug--in short, we re-build the widget instead of just
re-opening this.
We may also want the toggle component to simply default the
initial tab to the first tab.