This commit fixes an issue where the following happens:
1. The user opens a page where an alternative sidebar panel is displayed like /admin or other page where a plugin is displaying an alternative sidebar like the `docs-categories` plugin
2. Clicking the chat icon in the header and opening the drawer, or if you just minimize chat into drawer after it opens full-screen
3. The alternative sidebar panel is lost and reverted to the main panel.
There have been too many flaky tests as a result of leaking state in
Redis so it is easier to resolve them by ensuring we flush Redis'
database.
Locally on my machine, calling `Discourse.redis.flushdb` takes around
0.1ms which means this change will have very little impact on test
runtimes.
The script `send_chat_message` when used with the `post_created_edited` trigger now accepts `{{post_quote}}` as placeholder for the value of `message`.
This is made possible by a new method in `utils`. Usage:
```ruby
placeholders["foo"] = utils.build_quote(post)
```
On the chat channel settings page, we want to show a single Send push notifications setting instead of the current Desktop notifications and Mobile push notifications settings.
For existing users, use the Mobile push notifications setting value for the new Send push notifications setting.
While using `OpenStruct` is nice, it’s generally not a very good idea as
it usually leads to performance problems.
The `OpenStruct` source code even says basically to avoid it.
Since the context object is crucial in our services, this patch replaces
`OpenStruct` with a custom implementation instead.
This commit attempts to improve the mobile experience for
admin page header and subheader by automatically collapsing
all action buttons in these components into a DMenu when viewing
mobile.
This is done by using different "list" wrapper components and a
DMenu trigger and a DropdownMenu on mobile only, and uses has-block
to determine whether to render the DMenu trigger at all.
This also removes the `PluginOutlet` in `AdminPluginConfigPage`, it
was too inflexible for this `DropdownMenu` case, and since the `:actions`
were always rendering we couldn't rely on `has-block`. A new plugin API,
`registerPluginHeaderActionComponent`, has been introduced instead to
replace it.
Makes channel_id and is_direct_message_channel consistent across desktop notifications, which also removes the need to lookup the channel from Chat Notification Manager.
Currently in services, the `contract` step is only used to define where
the contract will be called in the execution flow. Then, a `Contract`
class has to be defined with validations in it.
This patch allows the `contract` step to take a block containing
validations, attributes, etc. directly. No need to then open a
`Contract` class later in the service.
It also has a nice side effect, as it’s now easy to define multiples
contracts inside the same service. Before, we had the `class_name:`
option, but it wasn’t really useful as you had to redefine a complete
new contract class.
Now, when using a name for the contract other than `default`, a new
contract will be created automatically using the provided name.
Example:
```ruby
contract(:user) do
attribute :user_id, :integer
validates :user_id, presence: true
end
```
This will create a `UserContract` class and use it, also putting the
resulting contract in `context[:user_contract]`.
In 61c1d35f17 I added a
PluginOutlet to AdminPluginConfigPage. This was intended to be
used as a way to render actions buttons inside the header of
a plugin that has a custom admin UI page. This worked, but
since the outlet was generically named, as soon as one plugin
used it the button would show on all plugins.
This fixes the immediate issue by naming the outlet based
on the plugin, then having each plugin specify their own
outlet to render into. There may be a nicer way to do this,
but for now this stops the bleeding.
With the current implementation, a service step can be written as:
```ruby
def my_step(a_default_value: 2)
…
end
```
That’s a pattern we want to avoid as default values (if needed) should
be probably defined in a contract.
This patch makes a service raise an exception if a default value is
encountered.
This will help to enforce a consistent pattern for creating service
actions.
This patch also namespaces actions and policies, making everything
related to a service available directly in
`app/services/<concept-name>`, making things more consistent at that
level too.
This change adds full names to direct message channel titles when the following conditions are met:
- SiteSetting.enable_names = true
- SiteSetting.display_name_on_posts = true
- SiteSetting.prioritize_username_in_ux = false
If a user's full name is blank, it will fallback to their username in both 1-1 channels and Group DM channels.
- fetch models inside services
- validate `user_id` in contracts
- use policy objects
- extract more logic to actions
- write specs for services and action
On occasion we get an error popup on desktop due to the channel not being found.
This change means that we only check the cached channels in ChatChannelsManager for the matching channel id, but we skip doing manual lookup which results in ajax popup when it fails.
This commit converts the current chat plugin UI into the
new "show plugin" UI already followed by AI and Gamification.
In the process, I also:
* Made a dedicated /new route to create new webhooks
* Converted the webhook form to FormKit
* Made some fixes and improvements to the `AdminPluginConfigPage`, `AdminPageHeader`,
and `AdminPageSubheader` generic components, so more plugins can
adopt the UI guidelines too. This includes adding a header outlet so plugins
can add action buttons to the plugin show page header.
* Fixes the submit button loading state for FormKit (by Joffrey)
---------
Co-authored-by: Joffrey JAFFEUX <j.jaffeux@gmail.com>
Every time a desktop chat sound plays, there should be some visual cue as to why the sound was played in the first place.
This change follows the chat indicator preference:
- All New Messages - a blue dot is shown for all messages, so we attempt to play a sound every time
- Direct Messages, Mentions and Watched Threads - a green dot is shown for all urgent messages, so we attempt to play a sound for urgent chat notifications
- Only Mentions - only play chat sounds when user is mentioned
- Never - we never play chat sounds, as user wouldn’t know why the sound was played
Chat toggle relies on using a height: auto to collapse drawer, however in channel threads we should be only displaying threads when drawer is expanded. Displaying threads conditionally based on drawer toggle status fixes this.
This change increases the visibility of unread channels to make them stand out more in drawer mode (desktop).
When a channel is unread:
- it floats to the top;
- when multiple channels are unread, they are sorted alphabetically (equal to how it’s done on mobile)
- the unread indicator blue dot moves to directly right of the channel name
This patch removes the `with_service` helper from the code base.
Instead, we can pass a block with actions directly to the `.call` method
of a service.
This simplifies how to use services:
- use `.call` without a block to run the service and get its result
object.
- use `.call` with a block of actions to run the service and execute
arbitrary code depending on the service outcome.
It also means a service is now “self-contained” and can be used anywhere
without having to include a helper or whatever.
We need to start printing deprecation notices when the `show_in_ui` argument is used because it works only for the old about page which will be removed soon. For the new about page, we've introduced a new API `addAboutPageActivity` which is more flexible than a true/false argument on the server side.
Internal topic: t/136551.
Currently, categories support designating only 1 group as a moderation group on the category. This commit removes the one group limitation and makes it possible to designate multiple groups as mods on a category.
Internal topic: t/124648.