`last_message_sent_at` has a `NOT_NULL` constraint in the DB so it should be safe to use for sorting.
This was causing two flakeys:
```
1) UserNotifications.chat_summary with public channel email subject with regular mentions includes both channel titles when there are exactly two with unread mentions
Failure/Error: example.run
expected: "[Discourse] New message in Random 62 and Test channel"
got: "[Discourse] New message in Test channel and Random 62"
(compared using ==)
# ./plugins/chat/spec/mailers/user_notifications_spec.rb:203:in `block (6 levels) in <main>'
# ./spec/rails_helper.rb:356:in `block (2 levels) in <top (required)>'
# ./vendor/bundle/ruby/3.1.0/gems/webmock-3.18.1/lib/webmock/rspec.rb:37:in `block (2 levels) in <top (required)>'
2) UserNotifications.chat_summary with public channel email subject with regular mentions displays a count when there are more than two channels with unread mentions
Failure/Error: example.run
expected: "[Discourse] New message in Random 62 and 2 others"
got: "[Discourse] New message in Test channel 0 and 2 others"
(compared using ==)
# ./plugins/chat/spec/mailers/user_notifications_spec.rb:236:in `block (6 levels) in <main>'
# ./spec/rails_helper.rb:356:in `block (2 levels) in <top (required)>'
# ./vendor/bundle/ruby/3.1.0/gems/webmock-3.18.1/lib/webmock/rspec.rb:37:in `block (2 levels) in <top (required)>'
```
|
||
|---|---|---|
| .. | ||
| app | ||
| assets | ||
| config | ||
| db | ||
| lib | ||
| public | ||
| spec | ||
| test/javascripts | ||
| plugin.rb | ||
| README.md | ||
⚠️ This plugin is still in active development and may change frequently
Documentation
The Discourse Chat plugin adds chat functionality to your Discourse so it can natively support both long-form and short-form communication needs of your online community.
For documentation, see Discourse Chat
Plugin API
registerChatComposerButton
Usage
api.registerChatComposerButton({ id: "foo", ... });
Options
Every option accepts a value or a function, when passing a function this will be the chat-composer component instance. Example of an option using a function:
api.registerChatComposerButton({
id: "foo",
displayed() {
return this.site.mobileView && this.canAttachUploads;
},
});
Required
idunique, used to identify your button, eg: "gifs"actioncallback when the button is pressed, can be an action name or an anonymous function, eg: "onFooClicked" or() => { console.log("clicked") }
A button requires at least an icon or a label:
icon, eg: "times"label, text displayed on the button, a translatable key, eg: "foo.bar"translatedLabel, text displayed on the button, a string, eg: "Add gifs"
Optional
position, can be "inline" or "dropdown", defaults to "inline"title, title attribute of the button, a translatable key, eg: "foo.bar"translatedTitle, title attribute of the button, a string, eg: "Add gifs"ariaLabel, aria-label attribute of the button, a translatable key, eg: "foo.bar"translatedAriaLabel, aria-label attribute of the button, a string, eg: "Add gifs"classNames, additional names to add to the button’s class attribute, eg: ["foo", "bar"]displayed, hide/or show the button, expects a booleandisabled, sets the disabled attribute on the button, expects a booleanpriority, an integer defining the order of the buttons, higher comes first, eg:700dependentKeys, list of property names which should trigger a refresh of the buttons when changed, eg:["foo.bar", "bar.baz"]