Commit Graph

245 Commits

Author SHA1 Message Date
06bbed69f9 DEV: allows a context when creating a message (#25647)
The service `Chat::CreateMessage` will now accept `context_post_ids` and `context_topic_id` as params. These values represent the topic which might be visible when sending a message (for now, this is only possible when using the drawer).

The `DiscourseEvent` `chat_message_created` will now have the following signature:

```ruby
on(:chat_message_created) do | message, channel, user, meta|
  p meta[:context][:post_ids]
end
```
2024-02-13 11:37:15 +01:00
04d2ec45b4 DEV: remove user thread count route (#25385)
Removes a now redundant route for the user thread count.
2024-01-24 10:32:34 +08:00
67244a2318 FIX: use site setting to show my threads chat footer tab (#25277)
Fixes an issue with delayed rendering of the My Threads tab in chat mobile footer.

Previously we made an ajax request to determine the number of threads a user had before rendering the tab, however it is much faster (and better UX) if we can rely on a site setting for this.

The new chat_threads_enabled site setting is set to true when the site has chat channels with threading enabled.
2024-01-23 19:14:46 +08:00
ccb5fa1a5a FIX: correctly exclude muted channels from thread unreads (#25339) 2024-01-19 22:05:41 +01:00
2014f1a0b7 FEATURE: implements dates separators for threads (#25335)
This commit creates a shared implementation of the dates computation and moves all the logic (new messages since last visit and dates separator into one single component <ChatMessageSeparator />).

The frontend tests have been removed and only a single system spec has been added for threads as everything is sharing the same implementation and the existing channel specs should catch any regression.
2024-01-19 16:21:48 +01:00
f4e51e0789 FEATURE: Allow users to DM groups in chat (#25189)
Allows users to create DMs by selecting groups as a target. It also allows adding user groups to an existing chat

- When creating the channel, it expands the user group and adds all its members with chat enabled to the channel.
- After creation, there's no difference between adding a group or adding its members individually.
- Users can add multiple groups and users simultaneously.
- There are UI validations; the member count preview updates according to the member count of added groups, and it does not allow users to add more members than SiteSetting.chat_max_direct_message_users."
2024-01-19 11:09:47 -03:00
610d5b45c7 FIX: errors when loading My Threads and Channel Threads (#25310)
This PR fixes the problems described below. We also need tests for this, 
they'll be in a follow-up. When there is a group mention inside a chat 
thread, the next problems are happening.

1. When trying to look at _My Threads_ the list of threads is failing to load 
and there are errors on the console:

Server Error in the current_user_threads_controller:

Message
ActiveRecord::AssociationNotFoundError (Association named 'user' was not 
found on Chat::GroupMention; perhaps you misspelled it?)

app/controllers/application_controller.rb:423:in `block in with_resolved_locale'
app/controllers/application_controller.rb:423:in `with_resolved_locale'
lib/middleware/omniauth_bypass_middleware.rb:64:in `call'
lib/content_security_policy/middleware.rb:12:in `call'
lib/middleware/gtm_script_nonce_injector.rb:10:in `call'
config/initializers/008-rack-cors.rb:14:in `call'
config/initializers/100-quiet_logger.rb:20:in `call'
config/initializers/100-silence_logger.rb:29:in `call'
lib/middleware/missing_avatars.rb:22:in `call'
lib/middleware/turbo_dev.rb:31:in `call'
Backtrace
activerecord (7.0.8) lib/active_record/associations.rb:302:in `association'
activerecord (7.0.8) lib/active_record/associations/preloader/branch.rb:79:in `block in grouped_records'
activerecord (7.0.8) lib/active_record/associations/preloader/branch.rb:77:in `each'
activerecord (7.0.8) lib/active_record/associations/preloader/branch.rb:77:in `grouped_records'
activerecord (7.0.8) lib/active_record/associations/preloader/branch.rb:114:in `loaders'
activerecord (7.0.8) lib/active_record/associations/preloader/branch.rb:71:in `runnable_loaders'
activerecord (7.0.8) lib/active_record/associations/preloader/batch.rb:15:in `each'
activerecord (7.0.8) lib/active_record/associations/preloader/batch.rb:15:in `flat_map'
activerecord (7.0.8) lib/active_record/associations/preloader/batch.rb:15:in `call'
activerecord (7.0.8) lib/active_record/associations/preloader.rb:118:in `call'
activerecord (7.0.8) lib/active_record/relation.rb:830:in `block in preload_associations'
activerecord (7.0.8) lib/active_record/relation.rb:829:in `each'
activerecord (7.0.8) lib/active_record/relation.rb:829:in `preload_associations'
activerecord (7.0.8) lib/active_record/relation.rb:918:in `block in exec_queries'
activerecord (7.0.8) lib/active_record/relation.rb:962:in `skip_query_cache_if_necessary'
activerecord (7.0.8) lib/active_record/relation.rb:908:in `exec_queries'
activerecord (7.0.8) lib/active_record/relation.rb:695:in `load'
activerecord (7.0.8) lib/active_record/relation.rb:250:in `records'
activerecord (7.0.8) lib/active_record/relation.rb:783:in `blank?'
plugins/chat/app/services/service/base.rb:143:in `call'
plugins/chat/app/services/service/base.rb:368:in `block in run!'
plugins/chat/app/services/service/base.rb:368:in `each'
plugins/chat/app/services/service/base.rb:368:in `run!'
plugins/chat/app/services/service/base.rb:361:in `run'
<internal:kernel>:90:in `tap'
plugins/chat/app/services/service/base.rb:229:in `call'
plugins/chat/app/helpers/chat/with_service_helper.rb:22:in `run_service'
plugins/chat/lib/service_runner.rb:121:in `call'
plugins/chat/lib/service_runner.rb:115:in `call'
plugins/chat/app/helpers/chat/with_service_helper.rb:18:in `with_service'
plugins/chat/app/controllers/chat/api/current_user_threads_controller.rb:5:in `index'
actionpack (7.0.8) lib/action_controller/metal/basic_implicit_render.rb:6:in `send_action'
actionpack (7.0.8) lib/abstract_controller/base.rb:215:in `process_action'
actionpack (7.0.8) lib/action_controller/metal/rendering.rb:165:in `process_action'
actionpack (7.0.8) lib/abstract_controller/callbacks.rb:234:in `block in process_action'
activesupport (7.0.8) lib/active_support/callbacks.rb:118:in `block in run_callbacks'
app/controllers/application_controller.rb:423:in `block in with_resolved_locale'
i18n (1.14.1) lib/i18n.rb:322:in `with_locale'
app/controllers/application_controller.rb:423:in `with_resolved_locale'
activesupport (7.0.8) lib/active_support/callbacks.rb:127:in `block in run_callbacks'
activesupport (7.0.8) lib/active_support/callbacks.rb:138:in `run_callbacks'
actionpack (7.0.8) lib/abstract_controller/callbacks.rb:233:in `process_action'
actionpack (7.0.8) lib/action_controller/metal/rescue.rb:23:in `process_action'
actionpack (7.0.8) lib/action_controller/metal/instrumentation.rb:67:in `block in process_action'
activesupport (7.0.8) lib/active_support/notifications.rb:206:in `block in instrument'
activesupport (7.0.8) lib/active_support/notifications/instrumenter.rb:24:in `instrument'
activesupport (7.0.8) lib/active_support/notifications.rb:206:in `instrument'
actionpack (7.0.8) lib/action_controller/metal/instrumentation.rb:66:in `process_action'
actionpack (7.0.8) lib/action_controller/metal/params_wrapper.rb:259:in `process_action'
activerecord (7.0.8) lib/active_record/railties/controller_runtime.rb:27:in `process_action'
actionpack (7.0.8) lib/abstract_controller/base.rb:151:in `process'
actionview (7.0.8) lib/action_view/rendering.rb:39:in `process'
rack-mini-profiler (3.3.0) lib/mini_profiler/profiling_methods.rb:115:in `block in profile_method' 
actionpack (7.0.8) lib/action_controller/metal.rb:188:in `dispatch'
actionpack (7.0.8) lib/action_controller/metal.rb:251:in `dispatch'
actionpack (7.0.8) lib/action_dispatch/routing/route_set.rb:49:in `dispatch'
actionpack (7.0.8) lib/action_dispatch/routing/route_set.rb:32:in `serve'
actionpack (7.0.8) lib/action_dispatch/journey/router.rb:50:in `block in serve'
actionpack (7.0.8) lib/action_dispatch/journey/router.rb:32:in `each'
actionpack (7.0.8) lib/action_dispatch/journey/router.rb:32:in `serve'
actionpack (7.0.8) lib/action_dispatch/routing/route_set.rb:852:in `call'
railties (7.0.8) lib/rails/engine.rb:530:in `call'
railties (7.0.8) lib/rails/railtie.rb:226:in `public_send'
railties (7.0.8) lib/rails/railtie.rb:226:in `method_missing'
actionpack (7.0.8) lib/action_dispatch/routing/mapper.rb:19:in `block in <class:Constraints>'
actionpack (7.0.8) lib/action_dispatch/routing/mapper.rb:48:in `serve'
actionpack (7.0.8) lib/action_dispatch/journey/router.rb:50:in `block in serve'
actionpack (7.0.8) lib/action_dispatch/journey/router.rb:32:in `each'
actionpack (7.0.8) lib/action_dispatch/journey/router.rb:32:in `serve'
actionpack (7.0.8) lib/action_dispatch/routing/route_set.rb:852:in `call'
lib/middleware/omniauth_bypass_middleware.rb:64:in `call'
rack (2.2.8) lib/rack/tempfile_reaper.rb:15:in `call'
rack (2.2.8) lib/rack/conditional_get.rb:27:in `call'
rack (2.2.8) lib/rack/head.rb:12:in `call'
actionpack (7.0.8) lib/action_dispatch/http/permissions_policy.rb:38:in `call'
lib/content_security_policy/middleware.rb:12:in `call'
lib/middleware/gtm_script_nonce_injector.rb:10:in `call'
config/initializers/008-rack-cors.rb:14:in `call'
rack (2.2.8) lib/rack/session/abstract/id.rb:266:in `context'
rack (2.2.8) lib/rack/session/abstract/id.rb:260:in `call'
actionpack (7.0.8) lib/action_dispatch/middleware/cookies.rb:704:in `call'
activerecord (7.0.8) lib/active_record/migration.rb:638:in `call'
actionpack (7.0.8) lib/action_dispatch/middleware/callbacks.rb:27:in `block in call'
activesupport (7.0.8) lib/active_support/callbacks.rb:99:in `run_callbacks'
actionpack (7.0.8) lib/action_dispatch/middleware/callbacks.rb:26:in `call'
actionpack (7.0.8) lib/action_dispatch/middleware/executor.rb:14:in `call'
actionpack (7.0.8) lib/action_dispatch/middleware/actionable_exceptions.rb:17:in `call'
actionpack (7.0.8) lib/action_dispatch/middleware/debug_exceptions.rb:28:in `call'
actionpack (7.0.8) lib/action_dispatch/middleware/show_exceptions.rb:29:in `call'
logster (2.14.0) lib/logster/middleware/reporter.rb:40:in `call'
railties (7.0.8) lib/rails/rack/logger.rb:40:in `call_app'
railties (7.0.8) lib/rails/rack/logger.rb:27:in `call'
config/initializers/100-quiet_logger.rb:20:in `call'
config/initializers/100-silence_logger.rb:29:in `call'
actionpack (7.0.8) lib/action_dispatch/middleware/remote_ip.rb:93:in `call'
actionpack (7.0.8) lib/action_dispatch/middleware/request_id.rb:26:in `call'
rack (2.2.8) lib/rack/method_override.rb:24:in `call'
actionpack (7.0.8) lib/action_dispatch/middleware/executor.rb:14:in `call'
actionpack (7.0.8) lib/action_dispatch/middleware/static.rb:23:in `call'
rack (2.2.8) lib/rack/sendfile.rb:110:in `call'
actionpack (7.0.8) lib/action_dispatch/middleware/host_authorization.rb:138:in `call'
lib/middleware/missing_avatars.rb:22:in `call'
lib/middleware/turbo_dev.rb:31:in `call'
rack-mini-profiler (3.3.0) lib/mini_profiler.rb:334:in `call'
message_bus (4.3.8) lib/message_bus/rack/middleware.rb:60:in `call'
railties (7.0.8) lib/rails/engine.rb:530:in `call'
railties (7.0.8) lib/rails/railtie.rb:226:in `public_send'
railties (7.0.8) lib/rails/railtie.rb:226:in `method_missing'
rack (2.2.8) lib/rack/urlmap.rb:74:in `block in call'
rack (2.2.8) lib/rack/urlmap.rb:58:in `each'
rack (2.2.8) lib/rack/urlmap.rb:58:in `call'
unicorn (6.1.0) lib/unicorn/http_server.rb:634:in `process_client'
unicorn (6.1.0) lib/unicorn/http_server.rb:739:in `worker_loop'
unicorn (6.1.0) lib/unicorn/http_server.rb:547:in `spawn_missing_workers'
unicorn (6.1.0) lib/unicorn/http_server.rb:143:in `start'
unicorn (6.1.0) bin/unicorn:128:in `<top (required)>'
bin/unicorn:93:in `load'
bin/unicorn:93:in `block in <main>'
bin/unicorn:92:in `fork'
bin/unicorn:92:in `<main>'

</details>

2. When looking at _channel threads_, threads are getting rendered successfully, 
but there are still errors on the console. The server error is similar to the first case, 
but it's in the `channel_threads_controller`.

This regression was introduced in 62f423da15edbbfbe4e37d218544a3e1ca427e6a.

The idea of the fix is that we only need to load user_mentions in those controllers 
anyway (we send them to the client in order to be able to show user status on mentions).
2024-01-18 17:35:32 +04:00
20c5f7aef8 PERF: Avoid loading the whole record when we only need id (#25301) 2024-01-18 08:50:26 +08:00
62f423da15 DEV: Redesign chat mentions (#24752)
At the moment, when someone is mentioning a group, or using here or 
all mention, we create a chat_mention record per user. What we want 
instead is to have special kinds of mentions, so we can create only one 
chat_mention record in such cases. This PR implements that.

Note, that such mentions will still have N related notifications, one 
notification per a user. We don't expect we'll have performance 
problems on the notifications side, but if at some point we do, we 
should be able to solve them on the side of notifications 
(notifications are handled in jobs, also some little delays with 
the notifications are acceptable, so we can make sure notifications 
are properly queued, and that processing of every notification is 
fast enough to make delays small enough).

The preparation work for this PR was done in fbd24fa, where we make 
it possible for one mention to have several related notifications.

A pretty tricky part of this PR is schema and data migration, I've explained 
related details inline on the migration files.
2024-01-17 15:24:01 +04:00
4512e5652f FEATURE: Mobile Chat Footer Redesign (#25161)
This update adds three tabs to the bottom of the chat overlay to make it easier for users to navigate chat on mobile.

As a result of this change:

- Direct Messages are now shown separately from public channels on mobile
- My Threads has now moved from the channel list to it's own tab on mobile
- My Threads can still be accessed on desktop via the sidebar and within the drawer channel list
- Chat back button has been updated to navigate to the correct tab (for both channels and threads)

Some special cases:

- If DMs are not used then the tab is not rendered
- If the user has no threads then the tab is not rendered
- If both the tabs for DMs and Threads aren't available then the whole footer will not be rendered
- Chat footer is only shown on the listing pages (DMs, Channels, My Threads)

---------

Co-authored-by: chapoi <101828855+chapoi@users.noreply.github.com>
Co-authored-by: Joffrey JAFFEUX <j.jaffeux@gmail.com>
2024-01-16 14:29:33 +08:00
26747540d2 FIX: Chat summary email link in subfolder setups (#25188)
This regressed in 2791e75072329fdbf9ebd6849cea3c63664b123c. That commit
fixed subfolder URLs in general, but the `full_url` was adding the
subfolder prefix a second time, thus breaking this URL in emails.
2024-01-10 11:52:57 -05:00
fd4ff92892 SECURITY: ensures mentioned_users is limited
Prior to this fix the number of users rendered by mentioned_users could equal the number of members in a channel which would be slow but could in more extreme case crash the page and/or server.
2024-01-08 08:02:13 -07:00
117611ea82 FIX: 500 error when reviewable has a missing message (#25113) 2024-01-03 11:49:54 -03:00
40ce619edd DEV: uses in: {} with lambda to work with eager_load (#25039)
When validating with a dynamic set of values, especially one that might change during runtime, we should use a lambda or a proc to ensure that the validation uses the most up-to-date set of values. This is particularly important when using config.eager_load = true, which can cause some elements to be loaded only once at startup, thus not reflecting changes made at runtime.

This was the root cause of the issues here, as we were adding more ReviewableScore types after initial load through: `register_reviewable_type Chat::ReviewableMessage`
2023-12-29 12:45:07 +08:00
fbd24fa6ae DEV: Allow chat mentions to have several notifications (#24874)
This PR is a reworked version of https://github.com/discourse/discourse/pull/24670.

In chat, we need the ability to have several notifications per `chat_mention`. 
Currently, we have one_to_one relationship between `chat_mentions` and `notifications`:

d7a09fb08d/plugins/chat/app/models/chat/mention.rb (L9)

We want to have one_to_many relationship. This PR implements that by introducing 
a join table between `chat_mentions` and `notifications`.

The main motivation for this is that we want to solve some performance problems 
with mentions that we're having now. Let's say a user sends a message with @ all 
in a channel with 50 members, we do two things in this case at the moment:

- create 50 chat_mentions
- create 50 notifications

We don't want to change how notifications work in core, but we want to be more 
efficient in chat, and create only 1 `chat_mention` which would link to 50 notifications. 
Also note, that on the side of notifications, having a lot of notifications is not so 
big problem, because notifications processing can be queued.

Apart from improving performance, this change will make the code design better.

Note that I've marked the old `chat_mention.notification_id` column as ignored, but 
I'm not deleting it in this PR. We'll delete it later in https://github.com/discourse/discourse/pull/24800.
2023-12-19 18:53:00 +04:00
22d8978eb4 FIX: increase default max length of chat message excerpts (#24842)
Increases the default max length of message excerpts to allow for longer titles in threads index.
2023-12-12 18:24:07 +08:00
09277bc543 FEATURE: my threads page (#24771)
This commit adds a new "My threads" link in sidebar and drawer. This link will open the "/chat/threads" page which contains all threads where the current user is a member. It's ordered by activity (unread and then last message created).

Moreover, the threads list of a channel page is now showing every threads of a channel, and not just the ones where you are a member.
2023-12-11 07:38:07 +01:00
694b5f108b DEV: Fix various rubocop lints (#24749)
These (21 + 3 from previous PRs) are soon to be enabled in rubocop-discourse:

Capybara/VisibilityMatcher
Lint/DeprecatedOpenSSLConstant
Lint/DisjunctiveAssignmentInConstructor
Lint/EmptyConditionalBody
Lint/EmptyEnsure
Lint/LiteralInInterpolation
Lint/NonLocalExitFromIterator
Lint/ParenthesesAsGroupedExpression
Lint/RedundantCopDisableDirective
Lint/RedundantRequireStatement
Lint/RedundantSafeNavigation
Lint/RedundantStringCoercion
Lint/RedundantWithIndex
Lint/RedundantWithObject
Lint/SafeNavigationChain
Lint/SafeNavigationConsistency
Lint/SelfAssignment
Lint/UnreachableCode
Lint/UselessMethodDefinition
Lint/Void

Previous PRs:
Lint/ShadowedArgument
Lint/DuplicateMethods
Lint/BooleanSymbol
RSpec/SpecFilePathSuffix
2023-12-06 23:25:00 +01:00
138bf486d3 DEV: Fix Lint/DuplicateMethods (#24746) 2023-12-06 13:18:34 +01:00
30d5e752d7 DEV: Revert guardian changes (#24742)
I took the wrong approach here, need to rethink.

* Revert "FIX: Use Guardian.basic_user instead of new (anon) (#24705)"

This reverts commit 9057272ee242b3bc977e50977b4142066c36c05d.

* Revert "DEV: Remove unnecessary method_missing from GuardianUser (#24735)"

This reverts commit a5d4bf6dd28a8304ccd519536f33bd4a13232ed4.

* Revert "DEV: Improve Guardian devex (#24706)"

This reverts commit 77b6a038bae010c9e9e630a137f9ccd570f60784.

* Revert "FIX: Introduce Guardian::BasicUser for oneboxing checks (#24681)"

This reverts commit de983796e1b66aa2ab039a4fb6e32cec8a65a098.
2023-12-06 16:37:32 +10:00
9057272ee2 FIX: Use Guardian.basic_user instead of new (anon) (#24705)
c.f. de983796e1b66aa2ab039a4fb6e32cec8a65a098

There will soon be additional login_required checks
for Guardian, and the intent of many checks by automated
systems is better fulfilled by using BasicUser, which
simulates a logged in TL0 forum user, rather than an
anon user.

In some cases the use of anon still makes sense (e.g.
anonymous_cache), and in that case the more explicit
`Guardian.anon_user` is used
2023-12-06 11:56:21 +10:00
c5aa6b5e16 FIX: correctly update replies_count on chat_threads (#24711)
The previous query would look at the existing messages, count them, and update the associated thread.

But, if for some reason messages were **ALL** deleted without updating the `replies_count`, then the query wouldn't find any message, and wouldn't update any thread's `replies_count`.
2023-12-05 13:46:58 +01:00
a1690e0401 DEV: removes dead code (message_link) (#24648)
Linking to a message ID is now handled by the frontend router: `chat.channel.near-message`
2023-11-30 11:13:37 +01:00
384a8b17a1 FIX: leaving a group channel should destroy membership (#24631)
In other kind of channels we will only unfollow but for group channels we don't want people to keep appearing in members list.

This commit also creates appropriate services:
- `Chat::LeaveChannel`
- `Chat::UnfollowChannel`

And dedicated endpoint for unfollow: `DELETE /chat/api/channels/:id/memberships/me/follows`
2023-11-29 17:48:14 +01:00
Sam
b09422428d DEV: update syntax tree to latest (#24623)
update format to latest syntax tree
2023-11-29 16:38:07 +11:00
ee5bdb3436 DEV: refactor flag message (#24604)
- Uses a chat service: `Chat::FlatMessage`
- Moves logic inside chat api controllers
- Create a javascript chat api helper: `chatApi.flagMessage(...)`
2023-11-28 18:24:09 +01:00
2befff5101 FIX: nullifies target message id when not readable (#24540)
This bug was very reproducible when your last read was a message you didn't read and an admin would delete it. When coming back to the channel you would get a not found, in this case we will now reset last read and present you the last message of the channel.

We could be more fancy and  try to detect the next readable message but that would be more code and complexity for such a rare case.
2023-11-24 11:46:00 +01:00
57584c38c0 FIX: correctly uses private_email site setting in chat (#24528)
Chat will now check for the state of `SiteSetting.private_email` when sending the summary, when enabled, the mail will not display user information, channel information other than the ID and no message information, only the count of messages.
2023-11-23 15:54:22 +01:00
17033d46c3 DEV: cooks messages synchronously (#24510)
Mentions and other post processing (like images) are still done asynchronously in the background. This should ensure reloading a channel while the message has not been processed yet doesn’t renders a blank message.

As a followup, we could probably simplify the staged message logic, given we have the new cooked on send.
2023-11-22 13:00:23 +01:00
906caa63d7 FEATURE: implements drafts for threads (#24483)
This commit implements drafts for threads by adding a new `thread_id` column to `chat_drafts` table. This column is used to create draft keys on the frontend which are a compound key of the channel and the thread. If the draft is only for the channel, the key will be `c-${channelId}`, if for a thread: `c-${channelId}:t-${threadId}`.

This commit also moves the draft holder from the service to the channel or thread model. The current draft can now always be accessed by doing: `channel.draft` or `thread.draft`.

Other notable changes of this commit:
- moves ChatChannel to gjs
- moves ChatThread to gjs
2023-11-22 11:54:23 +01:00
75e2c6b506 DEV: Pass the user who requested the summary to the strategy. (#24489)
This change allows the `discourse-ai` plugin to log the user who requested the summary in the `AiApiAuditLog`.
2023-11-21 13:27:27 -03:00
7f3f682f67 DEV: removes dead code (#24345) 2023-11-13 15:18:15 +01:00
ab832cc865 FEATURE: introduces group channels (#24288)
Group channels will allow users to create channels with a name and invite people. It's possible to add people even after creation of the channel. Removing users is not yet possible but will be added in the near future.

Technically a group channel is `direct_message_channel` with a group attribute set to true on its direct message (chatable). This model might evolve in the future but offers much flexibility for now without having to rely on a complex migration.

The commit essentially consists of:
- a migration to set existing direct message channels with more than 2 users to a group
- a new message creator which allows to search, add members, and create groups
- a new `AddUsersToChannel` service
- a modified `SearchChatable` service
2023-11-10 11:29:28 +01:00
039d060832 DEV: improves reliability of delete/restore/update specs (#24265) 2023-11-07 11:34:35 +01:00
90efdd7f9d PERF: cook message in background (#24227)
This commit starts from a simple observation: cooking messages on the hot path can be slow. Especially with a lot of mentions.

To move cooking from the hot path, this commit has made the following changes:

- updating cooked, inserting mentions and notifying user of new mentions has been moved inside the `process_message` job. It happens right after the `Chat::MessageProcessor` run, which is where the cooking happens.
- the similar existing code in `rebake!` has also been moved to rely on the `process_message`job only
- refactored `create_mentions` and `update_mentions` into one single `upsert_mentions` which can be called invariably
- allows services to decide if their job is ran inline or later. It avoids to need to know you have to use `Jobs.run_immediately!` in this case, in tests it will be inline per default
- made various frontend changes to make the chat-channel component lifecycle clearer. we had to handle `did-update @channel` which was super awkward and creating bugs with listeners which the changes of the PR made clear in failing specs
- adds a new `-processed` (and `-not-processed`) class on the chat message, this is made to have a good lifecyle hook in system specs
2023-11-06 15:45:30 +01:00
db880d8ed7 DEV: adds a :chat_thread_created trigger (#24133)
Usage:

```ruby
DiscourseEvent.on(:chat_thread_created) do |thread|
end
```
2023-10-27 10:27:34 +02:00
5fec841c19 FIX: ensures users can open channel invites (#24067)
We were incorrectly generating URLs with message id even when it was not provided, resulting in a route ending with "undefined", which was causing an error.

This commit also uses this opportunity to:
- move `invite_users` into a proper controller inside the API namespace
- refactors the code into a service: `Chat::InviteUsersToChannel`
2023-10-24 18:51:33 +02:00
f1e22dfebd FEATURE: add grace period for chat edits (#23800)
This change allows users to edit their chat messages based on the criteria added to Site Settings.

If the grace period conditions are met then there will be no (edited) text applied to the message.

The following site settings are added to chat:

chat editing grace period (seconds since message created)
chat editing grace period max diff for low trust levels (number of characters changed)
chat editing grace period max diff for high trust levels (number of characters changed)
2023-10-23 16:40:30 +08:00
d1ef6ab99f FIX: do not serialize status when profile is hidden (#23946)
Users can decide to hide their profile and presence. It seems more correct to also not return the status in this case.

Co-authored-by: Penar Musaraj <pmusaraj@gmail.com>
2023-10-16 17:43:39 +02:00
6350ba2cb3 SECURITY: Add permissions to MessageBus in chat
Add spec

compact
2023-10-16 10:34:30 -04:00
dfe840f71d FIX: properly create a mention when followed by dots (#23829)
At the moment writing a mention similar to `@bob...hi` would have resulted in chat trying to find a user named `bob...hi` which would fail.

This was due to the `replacements` rule not being present in the rules used to cook chat messages.

We are still missing few default rules like: normalize, smartquotes, text_join, ... which don't seem to be necessary but could be added if we found a reason for. More info at: e476f78bc3/lib/parser_core.js
2023-10-09 08:30:18 +02:00
79ececd976 FIX: handle thread participants limit on the frontend (#23839)
Workaround for an issue we are experiencing on thread index frontend where thread loads participants correctly (up to 10), then refreshes the threads and then limits to 3 participants.

There is an issue with storing threads for the main channel view and the thread list in the same store so handling the max participants on the frontend is a workaround until channel.threadsManager is updated.

I've adjusted the tests to handle the additional data being returned from ThreadParticipantQuery.
2023-10-09 14:04:59 +08:00
057c2012f0 UX: remove excerpt + style change to thread list item (#23776)
UX changes to thread item:

- drop "last reply" timestamp copy
- drop last reply excerpt
- show up 9+OP members

Co-authored-by: David Battersby <info@davidbattersby.com>
2023-10-06 15:11:04 +02:00
8447928840 DEV: enforces system user membership (#23771)
System user will automatically adds itself to the channel when trying to send a message.
2023-10-04 17:03:23 +02:00
e3e94aec95 FIX: ensures we reuse existing thread if existing (#23618)
This is a special case to ensure that if two users start a thread at the same time, we won't attempt to create a second thread.
2023-09-26 10:15:16 +02:00
92839dc722 FIX: ensures an empty last message won't cause errors (#23647)
This would cause an error when deleting the original message of a thread, due to the non existing `last_message`. This fix is implemented using the null pattern.

Note this commit is also using this opportunity to unify naming of null objects, `Chat::DeletedUser` becomes `Chat::NullUser`, it feels better to have a name describing what is the object, instead of a name describing why this object has to be used, which can change depending on cases.
2023-09-25 12:43:04 +02:00
2791e75072 FEATURE: Link chat notifications directly to message (#23617)
- Updates `Chat::Message#url` to work in threads and for subfolder
- Updates Jobs::Chat::NotifyWatching to use message URL instead of channel url
2023-09-16 20:37:35 +01:00
c8fff19b99 DEV: removes the notion of staged thread (#23612)
While very fast and powerful staged threads forces a lot of gymnastic and edge cases. This patch adds a new service `Chat::CreateThread` and uses it to create a thread unconditionally when a user replies to a message in a threading enabled channel. If the user actually doesn’t send a message we will have a thread with no messages which has no important impact and could even be periodically cleaned if necessary.

Note that this commit also moves message actions to .gjs as it was the original goal of this PR to correctly check for staged thread to show the menu or not.
2023-09-15 18:09:45 +02:00
16ccf30abc DEV: add maxlength limits to chat messages and revisions (#23530)
Add additional limits to text columns for chat.
2023-09-12 18:02:04 +08:00
6e672557fa DEV: add maxlength to additional chat text columns (#23505)
Add additional limits to text columns for chat.
2023-09-12 14:52:50 +08:00