This commit fixes an issue where the chat message bookmarks
did not respect the user's `bookmark_auto_delete_preference`
which they select in their user preference page.
Also, it changes the default for that value to "keep bookmark and clear reminder"
rather than "never", which ends up leaving a lot of expired bookmark
reminders around which are a pain to clean up.
* DEV: Remove enable_whispers site setting
Whispers are enabled as long as there is at least one group allowed to
whisper, see whispers_allowed_groups site setting.
* DEV: Always enable whispers for admins if at least one group is allowed.
This PR adds a new "Pause notifications" checkbox to the user status modal. This checkbox allows enabling the Do-Not-Disturb mode together with user status. Note that we don't remove and don't rename the existing DnD menu item in this PR, so the old way of entering the DnD mode is still available.
Also, we're not making DnD mode a part of user status on backend and in database. The reason is that the DnD mode should still be available on sites with disabled user status, having them separated helps keep the implementation simple.
We were changing the user's user_option.bookmark_auto_delete_preference
to whatever they changed it to in the bookmark modal to use as default
for future bookmarks. However this was leading to a lot of confusion
since if you wanted to set it for one bookmark you had to remember to
change it back on the next one.
This commit removes that automatic functionality, and instead moves
the bookmark auto delete preference to User Preferences > Interface
in an explicit dropdown.
Fixes an issue on mobile where navigating away from search and returning
results in confusing UI where there are no results but headings says "N
results found".
1. "What Goes Up Must Come Down" – if you subscribe to message bus, make sure you also unsubscribe
2. When you unsubscribe - remove only your subscription, not **all** subscriptions on given channel
Attempt #2. The first attempt tried to extend a core `@bound` method in new-user-narrative plugin which did not work. I reworked that plugin in the meantime. This new PR also cleans up message bus subscriptions in now core-merged chat plugin.
A translator noted that this string is odd: "We'll email you immediately
if you haven't read the thing we're emailing you about." We show this
note in the user profile when the user has chosen to be emailed "only
when away" and the site has `email_time_window_mins` off. The message
essentially says that "only when away" in this particular site's config
means "Always".
I think it is best to show no description here. In an ideal world, the
"Only when away" option shouldn't be there when `email_time_window_mins`
is off. But it is rare to choose that override, and adding proper support
for that use case would be complicated.
This new site setting replaces the
`enable_experimental_sidebar_hamburger` and `enable_sidebar` site
settings as the sidebar feature exits the experimental phase.
Note that we're replacing this without depreciation since the previous
site setting was considered experimental.
Internal Ref: /t/86563
In this PR, we introduced an option, that when all authenticators are disabled, but backup codes still exists, user can authenticate with those backup codes. This was reverted as this is not expected behavior.
https://github.com/discourse/discourse/pull/18982
Instead, when the last authenticator is deleted, backup codes should be deleted as well. Because this disables 2fa, user is asked to confirm that action by typing text.
In addition, UI for 2fa preferences was refreshed.
* FIX: Save only visible fields from the sidebar page
* FIX: Do not reset seen popups when set to false
If the option was unchecked, but it was not changed at all by the user
it was still sent to the server as a 'false' value which reset all seen
popups. This removes that behavior and resetting the list of seen popups
must be done using the "skip new user tips" button.
That was a weird UX (why hide the preferences navigation?) and a deprecated implementation (manually rendering a template into a named outlet)
This PR replaces it with an inline component.
* FEATURE: Show warning if group cannot be mentioned
A similar warning is displayed when the user cannot be mentioned because
they have not been invited to the topic.
* FEATURE: Resolve mentions for new topic
This commit improves several improvements and refactors
/u/is_local_username route to a better /composer/mentions route that
can handle new topics too.
* FEATURE: Show warning if only some are notified
Sometimes users are still notified even if the group that was mentioned
was not invited to the message. This happens because its members were
invited directly or are members of other groups that were invited.
* DEV: Refactor _warnCannotSeeMention
User options were serialized at the root level of CurrentUserSerializer,
but UserSerializer has a user_option field. This inconsistency caused
issues in the past because user_option fields had to be duplicated on
the frontend.
With the refactoring of the user messages routes in
4da2e3fef4, we can now depend on the top
level routes like `userPrivateMessages.user`, `userPrivateMessages.group` and `userPrivateMessages.tags`
to determine what the active value for the dropdown should be which
greatly simplifies the logic.
Currently this is how the navigation structure looks like on the messages page:
#### When personal inbox route is active
```
Inbox
sent
new
unread
archive
Group 1 Inbox
Group 2 Inbox
Tags
<Plugin Outlet>
```
#### When group inbox route is active
```
Inbox
Group 1 Inbox
sent
new
unread
archive
Group 2 Inbox
Tags
<Plugin Outlet>
```
With the existing structure, it is very easy for plugins to add additional navigation links by using the plugin outlet. In the redesigned user page navigation, the navigation structure on the messages page has been changed to look like this:
#### When personal inbox route is active
```
---dropdown-------
| Inbox | Latest | Sent | New | Unread | Archive
------------------
```
#### When group inbox route is active
```
---dropdown------
| Group 1 Inbox | Latest | New | Unread | Archive
-----------------
```
With the new navigation structure, we can no longer rely on a simple plugin outlet to extend the navigation structure. Instead, we will need to introduce a plugin API for plugins to extend the navigation structure. The API needs to allow two things to happen:
1. The plugin API needs to allow the plugin to register an item in the drop down and for the registered item to be "selected" whenever the plugin's routes are active.
1. The plugin API needs to allow the plugin to register items into the secondary horizontal navigation menu beside the drop down.
While trying to design the API, I struggle with trying to determine the "context" of the current route. In order words, it was hard to figure out if the current user is viewing the personal inbox, group inbox or tags. This is attributed to the fact that our current routing structure looks like this:
```
this.route(
"userPrivateMessages",
{ path: "/messages", resetNamespace: true },
function () {
this.route("new");
this.route("unread");
this.route("archive");
this.route("sent");
this.route("warnings");
this.route("group", { path: "group/:name" });
this.route("groupArchive", { path: "group/:name/archive" });
this.route("groupNew", { path: "group/:name/new" });
this.route("groupUnread", { path: "group/:name/unread" });
this.route("tags");
this.route("tagsShow", { path: "tags/:id" });
}
);
```
In order to provide context of the current route, we currently require all child routes under the `userPrivateMessages` route to set a `pmView` property on the `userPrivateMessages` controller. If the route requires additional context like the group currently active on the group inbox routes, the child routes would then have to set the `group` property on the `userPrivateMessages` controller. The problems with this approach is that we end up with many permutations of state on the `userPrivateMessages` controller and have to always clean up the state when navigating between the child routes. Basically, data is flowing upwards from the child routes into the parent controller which is not an ideal approach because we cannot easily determine where the "data" setup happens. Instead, we want to follow something similar to the "Data down, actions up" pattern where data flows downwards. In this commit, the `userPrivateMessages` routes have been changed to look like this:
```
this.route(
"userPrivateMessages",
{ path: "/messages", resetNamespace: true },
function () {
this.route("user", { path: "/" }, function () {
this.route("new");
this.route("unread");
this.route("archive");
this.route("sent");
this.route("warnings");
});
this.route("group", { path: "group/:name" }, function () {
this.route("archive");
this.route("new");
this.route("unread");
});
this.route("tags", { path: "/tags" }, function () {
this.route("show", { path: ":id" });
});
}
);
```
Basically, we group the child routes based on the purpose each route servers. User inbox routes are grouped together while group inbox routes are grouped together. A big benefit of this is that now have a different Ember router and controller for each grouping of child routes. The context of the current route is then tied directly to the route name instead of requiring each child route to set an attribute on the parent controller.
The second reason for why we needed to group the child routes together is because it allows us to pass the responsibility of rendering the secondary navigation links to the child routes. In this commit, we use the `{{in-element}}` modifier in the child route to render the secondary navigation links.
```
---dropdown--------
| Group 1 Inbox | Latest | New | Unread | Archive
------------------------
<parent template> <horizontal secondary navigation links element>
```
This means that each child route with its own model and context can then handle the responsibility of rendering the secondary navigation links without having to pass its context up to the `userPrivateMessages` controller. While this should have simplified by the `userPrivateMessages` controller, we can't do that in this commit because our current navigation structure requires all links for all message inboxes to remain on screen at all times. Once we fully transition to the redesigned user menu navigation, we will be able to greatly simplify things around the routes and controllers for `userPrivateMessages`.
In an ideal world, we would deprecate the old routes but I have done a quick search through all known plugins and no plugins are currently relying on those routes. There is a chance we could break plugins here but I'll like to see some smoke first before committing to the effort of deprecating client side routes.
1. "What Goes Up Must Come Down" – if you subscribe to message bus, make sure you also unsubscribe
2. When you unsubscribe - remove only your subscription, not **all** subscriptions on given channel
When sidebar was enabled before going to narrow screen, it should be brought back when screen is enlarged.
Also, narrow screen value is changed to 1000px instead of 1100px.
This will be used by plugins to handle the client side of their custom
post validations without having to overwrite the whole composer save
action as it was done in other plugins.
Co-authored-by: Penar Musaraj <pmusaraj@gmail.com>
The user preferences tracking page is only present when the redesign
user navigation menu is enabled. During the first pass of
implementation, some old bugs were introduced and this commit fixes
that. Regression tests have also been added.
Trying out changes to reduce the number of nav items in the experimental horizontal user nav. These changes should only appear with the redesigned_user_page_nav_enabled feature flag.
1. Created a new "Tracking" route. This combines some tracking-related settings from Notifications and Category and Tag tracking (which were separate tabs previously). Don't love the layout yet, but it's something that we can work on.
2. Moved some user-related settings out of Notifications and to the
Users tab. These seem more user-related to me, and it's nice that we can
associate enabling messages with the setting to limit who can send
messages.
3. Moved the App tab (lists app permissions) to be within the Security tab. It's very similar to Recently Used Devices.
* FIX: allow tl4 to bulk select
- Also allows tl4 to perform batch tagging
---
Long term this needs to be rewritten to account for "bulk action" permission
given from the server.
Co-authored-by: Martin Brennan <martin@discourse.org>
TrackedObject allows us to reference SiteSettings in autotracking contexts (e.g. JS getters referenced from a Glimmer template) without the need for EmberObject's `get()` function. TrackedObject is backwards-compatible with Ember's legacy reactivity model, so it can be referenced in things like computed properties.
Co-authored-by: David Taylor <david@taylorhq.com>
When opening the invite acceptance page when the user
was already logged in, we were still showing the Accept
Invitation prompt even if the user had already redeemed
the invitation and was present in the `InvitedUser` table.
This would lead to errors when the user clicked on the button.
This commit fixes the issue by hiding the Accept Invitation
button and showing an error message instead indicating that
the user had already redeemed the invitation. This only applies
to multi-use invite links.
* FIX: Update user options only once
Performing actions that updated list of seen popups used to update user
options everytime instead of checking if the change has any effect.
* FIX: Load updated user data from response
* DEV: Add utility to hide all user tips
* DEV: Add UserTip Glimmer component
* DEV: Add tests for existing user tips
* FEATURE: Add user tip for post menu
* FEATURE: Add user tip for topic notification level
* FEATURE: Add user tip for suggested topics
* FEATURE: Hide new popups for existing users
Currently, we have available three 2fa methods:
- Token-Based Authenticators
- Physical Security Keys
- Two-Factor Backup Codes
If the first two are deleted, user lose visibility of their backup codes, which suggests that 2fa is disabled.
However, when they try to authenticate, the account is locked, and they have to ask admin to fix that problem.
This PR is fixing the issue. User still sees backup codes in their panel and can use them to authenticate.
In next PR, I will improve UI to clearly notify the user when 2fa is fully disabled and when it is still active.
Repro steps:
- enable permanent deletes (via hidden site setting)
- set `min_topic_views_for_delete_confirm` to 0
When permanently deleting, the delete confirm modal is shown (for a
second time) and it doesn't pass the `force_destroy` parameter to the
request and the action results in a 422 error (i.e. can't perma-delete).
This change skips showing the confirm modal when perma-deleting given
that it has already been show on the first delete action.
This updates the behavior of the list destination setting for links in the sidebar.
By default, new/unread content will show a dot like chat, rather than the count of new/unread topics.
If a user chooses to link to new/unread in the sidebar, we'll show the count.
The goal here is to find a simple default for typical users (new/unread indication, no counts, default links) while providing a different workflow for power users (showing new/unread counts, and linking directly to new/unread).
Internal Ref: /t/82626
This commit fixes a bug on the client site where we would include the
`regular_category_ids` field when trying to update the notification levels of
categories for a user. The `regulary_category_ids` field should only be
included when the `mute_all_categories_by_default` is enabled
The clientside allowPersonalMessages function introduced
in e62e93f83a sometimes did not
work correctly, because the currentUser.groups property
only contained **visible** groups for the current user, which
could exclude auto groups that had their permissions set to
be owner-only visible.
It was unnecessary to add this anyway since we already have
can_send_private_messages on the CurrentUserSerializer. It's
better the backend does this calculation anyway. Use that
in the clientside code instead and get rid of allowPersonalMessages
Debouncing inline anonymous functions does not work.
This fixes all instances of that error by extracting the function or using the new `@debounce(delay)` decorator
Before, `sidebar_list_destination` was an attribute on UserOptionSerializer. The problem was that this attribute was added to user model only when the user entered the preferences panel. We want that attribute to be available all the time, therefore it was moved to CurrentUserSerializer.