In this PR service objects were moved to Core https://github.com/discourse/discourse/pull/26506
However, ServiceRunner should be moved as well. Mostly for CI to run effortlessly without loading plugins.
Prior to this fix we had too logic to detect if a user is active or not:
- idle codepath on the frontend
- online user ids on the backend
The frontend solution is not very reliable, and both solution are just trying to be too smart. Making a lot of people questioning why they receive a notification sometimes and sometimes not. This commit removes all this logic and replaces it with a much more simpler logic:
- you can't receive notifications for channel you are actually watching
- we won't play a sound more than once every 3seconds
The `onNotification` signature is:
```
onNotification(data, siteSettings, user, appEvents)
```
And we were not passing `appEvents`.
Also explicitly inject `currentUser` in `chat-notification-manager` service.
We consider that you should always receive a notification sound when someone speaks directly with you in chat.
This commit also refactors the way we play audio in chat to make it simpler and throttle it to 3 seconds.
We also added a safeguard to ensure we won't play sounds for old messages, this case can happen when message bus is catching up the backlog (eg: in an inactive tab for example).
When users click a link that points to an existing group chat, we should reopen that chat instead of creating a new group chat so users can more easily continue ongoing conversations.
activeChannel is something we should use less and less as it could not exist, in this case we have the channel right here in the function so there's no reason to reach for `this.chat.activeChannel`.
Prior to this fix we wouldn't intercept it, and we also wouldn't handle it, which in result would cause us to handle as a full page interaction and open the full page chat even if you were in drawer mode.
When a user had the chat option "Show activity indicator in header" set to "all new messages", and they would get a reply to a thread they're part of, the chat icon in the header would not show the unread bubble indicator.
In order to fix this, the `ChatHeaderIconUnreadIndicator` component will now `showUnreadIndicator` whenever there is either one unread public channel or there are unread threads.
I only added a system spec for this very specific path because I don't want to slow down the whole suite to test for all the various combination of the `chat_header_indicator_preference` values.
Internal ref - t/128874
Not 100% sure why the changes in `PrettyText.format_for_email` raised this issue, but we were missing adding a link to the Discourse instance whenever we are replacing the elided part of a post with a link to either the post or the Discourse instance in the email.
Also reformated the specs using better variable names (sometimes a variable named `md` would contain some html) and used the `match_html` helper for all the tests.
Given this is currently buggy and we have the cancel button Im not sure this is actually necessary. I feel like it's adding a lot of noise of low value.
For now at least, it's better without it.
This commit reuses the existing codepath in desktop-notifications and make it available to use to chat.
primaryTab was too hard to test if not impossible in this service test, however isIdle and disabled notifications are correctly tested.
Prior to this change, only mentions would get a notification and a sound. This change will not create a notification for this case, but will play a sound. This is still respecting notification settings, not playing the sound when you are viewing the channel or not following it.
---------
Co-authored-by: Régis Hanol <regis@hanol.fr>
(experimental)
The initial implementation of glimmer topic-list and related components. Does not include new APIs and isn't compatible with existing customization. That's gonna come in future PRs.
Enabled by adding groups to `experimental_glimmer_topic_list_groups` setting.
Debouncing the audio was causing the audio to be lost sometimes, somewhat randomly. It's not supposed to be necessary.
The commit also refactors the code to async/await.
Prior to this fix we were using `topic.current_post_number` which is coming from the server side and represents the initial topic scroll position when initially rendered to the end user. However, this value is not dynamic and is not updated when the user scrolls, `topic.currentPost` is the dynamic equivalent.
No test as there are very low chances a test like this one based on scroll position, will be reliable over time.
... wasn't properly escaped so it would should html entities (like `'` instead of the apostrophe `'`).
I checked all the other places we show an excerpt and this was the only one that was missing the call to `htmlSafe` -> `replaceEmoji`.
Internal ref - t/128877
The translations of the labels of some of the chat preferences dropdowns were not customizable via the "site texts" feature.
This was because they were declared outside of a Controller class and were thus not taking into account the customization through "site texts".
Internal ref - t/128859
When you reply to a chat message, we [always create a thread][1]. But when the channel we're in doesn't have threading enabled, the reply is _technically_ not a thread.
This changes the `in_thread?` method to check for both the presence of a `thread_id` and to ensure that the channel has `threading_enabled`.
Internal ref - t/128103/3
[1]: e6e3eaf472/plugins/chat/app/services/chat/create_message.rb (L110-L115)
Whenever you get a bookmark notification, a mention notification, or click on a bookmark on a message in a long thread, we should ensure we always highlight and show the proper message.
Before this fix, we would correctly load the thread, but would always start at the bottom.
Internal ref. t/128103
For both `chat_allowed_groups` and `chat_message_flag_allowed_groups`,
this commit removes the `is_staff?` guardian check, and instead
adds both `moderators` and `admins` auto groups as `mandatory_values`
to those settings, as part of an ongoing effort to do this for
group-based setting values.
The automation plugin has 4 custom field types that are array typed. However, array typed custom fields are deprecated and should be migrated to JSON type.
This commit does a couple of things:
1. Migrate all four custom fields to JSON
2. Fix a couple of small bugs that have been discovered while migrating the custom fields to JSON (see the comments on this commit's PR for details https://github.com/discourse/discourse/pull/26939)
Some combinations of start_date and frequency/interval values can cause a recurring automation rule to either trigger before its start_date or never trigger. Example repros:
- Configure a recurring automation with hourly recurrence and a start_date several days ahead. What this will do is make the automation start running hourly immediately even though the start_date is several days ahead.
- Configure a recurring automation with a weekly recurrence and a start_date several weeks ahead. This will result in the automation never triggering even after the start_date.
These 2 scenarios share the same cause which is that the automation plugin doesn't use the start_date as the date for the first run and instead uses the frequency/interval values from the current time to calculate the first run date.
This PR fixes this bug by adding an explicit check for start_date and using it as the first run's date if it's ahead of the current time.
This change adds a wrapper link around the thread list details on mobile to make the click area larger.
We also update child div elements to span to ensure valid html, since the link is an inline element and divs are block level.
---------
Co-authored-by: chapoi <101828855+chapoi@users.noreply.github.com>
We were missing two `getURL` calls.
The test is now written for subfolder but it's good enough. If it's working for subfolder, it's working for non subfolders, the opposite being false.
menus and tooltips are now appended to their own portals. The service are the only responsible for managing the instances, prior to this commit, services could manage one instance, but the DMenu and DTooltip components could also take over which could cause unexpected states.
This change also allows nested menus/tooltips.
Other notable changes:
- few months ago core copied the CloseOnClickOutside modifier of float-kit without removing the float-kit one, this commit now only use the core one.
- the close function is now trully async
- the close function accepts an instance or an identifier as parameter
Whenever a post already failed "lightweight" validations, we skip all the expensive validations (that cooks the post or run SQL queries) so that we reply as soon as possible.
Also skip validating polls when there's no "[/poll]" in the raw.
Internal ref - t/115890
- prevents re-rendering avatars while updating messages quickly in the thread preview indicator
- ensures the cancel button is shown when you are admin OR when the streamed message is a reply to the current user